|
|
1.1 ! root 1: /* Routines to generate code for I/O statements. ! 2: Some corrections and improvements due to David Wasley, U. C. Berkeley ! 3: */ ! 4: ! 5: /* TEMPORARY */ ! 6: #define TYIOINT TYLONG ! 7: #define SZIOINT SZLONG ! 8: ! 9: #include "defs" ! 10: ! 11: LOCAL int doiolist(), dofclose(), dofinquire(), dofopen(), dofmove(), ! 12: ioset(), ioseta(), iosetc(), iosetip(), iosetlc(), putio(), ! 13: putiocall(); ! 14: ! 15: ! 16: LOCAL char ioroutine[XL+1]; ! 17: ! 18: LOCAL int ioendlab; ! 19: LOCAL int ioerrlab; ! 20: LOCAL int endbit; ! 21: LOCAL int errbit; ! 22: LOCAL int jumplab; ! 23: LOCAL int skiplab; ! 24: LOCAL int ioformatted; ! 25: LOCAL int statstruct = NO; ! 26: LOCAL ftnint blklen; ! 27: ! 28: #define UNFORMATTED 0 ! 29: #define FORMATTED 1 ! 30: #define LISTDIRECTED 2 ! 31: #define NAMEDIRECTED 3 ! 32: ! 33: #define V(z) ioc[z].iocval ! 34: ! 35: #define IOALL 07777 ! 36: ! 37: LOCAL struct Ioclist ! 38: { ! 39: char *iocname; ! 40: int iotype; ! 41: expptr iocval; ! 42: } ! 43: ioc[ ] = ! 44: { ! 45: { "", 0 }, ! 46: { "unit", IOALL }, ! 47: { "fmt", M(IOREAD) | M(IOWRITE) }, ! 48: { "err", IOALL }, ! 49: { "end", M(IOREAD) }, ! 50: { "iostat", IOALL }, ! 51: { "rec", M(IOREAD) | M(IOWRITE) }, ! 52: { "recl", M(IOOPEN) | M(IOINQUIRE) }, ! 53: { "file", M(IOOPEN) | M(IOINQUIRE) }, ! 54: { "status", M(IOOPEN) | M(IOCLOSE) }, ! 55: { "access", M(IOOPEN) | M(IOINQUIRE) }, ! 56: { "form", M(IOOPEN) | M(IOINQUIRE) }, ! 57: { "blank", M(IOOPEN) | M(IOINQUIRE) }, ! 58: { "exist", M(IOINQUIRE) }, ! 59: { "opened", M(IOINQUIRE) }, ! 60: { "number", M(IOINQUIRE) }, ! 61: { "named", M(IOINQUIRE) }, ! 62: { "name", M(IOINQUIRE) }, ! 63: { "sequential", M(IOINQUIRE) }, ! 64: { "direct", M(IOINQUIRE) }, ! 65: { "formatted", M(IOINQUIRE) }, ! 66: { "unformatted", M(IOINQUIRE) }, ! 67: { "nextrec", M(IOINQUIRE) }, ! 68: { "nml", M(IOREAD) | M(IOWRITE) } ! 69: }; ! 70: ! 71: #define NIOS (sizeof(ioc)/sizeof(struct Ioclist) - 1) ! 72: #define MAXIO SZFLAG + 10*SZIOINT + 15*SZADDR ! 73: ! 74: #define IOSUNIT 1 ! 75: #define IOSFMT 2 ! 76: #define IOSERR 3 ! 77: #define IOSEND 4 ! 78: #define IOSIOSTAT 5 ! 79: #define IOSREC 6 ! 80: #define IOSRECL 7 ! 81: #define IOSFILE 8 ! 82: #define IOSSTATUS 9 ! 83: #define IOSACCESS 10 ! 84: #define IOSFORM 11 ! 85: #define IOSBLANK 12 ! 86: #define IOSEXISTS 13 ! 87: #define IOSOPENED 14 ! 88: #define IOSNUMBER 15 ! 89: #define IOSNAMED 16 ! 90: #define IOSNAME 17 ! 91: #define IOSSEQUENTIAL 18 ! 92: #define IOSDIRECT 19 ! 93: #define IOSFORMATTED 20 ! 94: #define IOSUNFORMATTED 21 ! 95: #define IOSNEXTREC 22 ! 96: #define IOSNML 23 ! 97: ! 98: #define IOSTP V(IOSIOSTAT) ! 99: ! 100: ! 101: /* offsets in generated structures */ ! 102: ! 103: #define SZFLAG SZIOINT ! 104: ! 105: /* offsets for external READ and WRITE statements */ ! 106: ! 107: #define XERR 0 ! 108: #define XUNIT SZFLAG ! 109: #define XEND SZFLAG + SZIOINT ! 110: #define XFMT 2*SZFLAG + SZIOINT ! 111: #define XREC 2*SZFLAG + SZIOINT + SZADDR ! 112: #define XRLEN 2*SZFLAG + 2*SZADDR ! 113: #define XRNUM 2*SZFLAG + 2*SZADDR + SZIOINT ! 114: ! 115: /* offsets for internal READ and WRITE statements */ ! 116: ! 117: #define XIERR 0 ! 118: #define XIUNIT SZFLAG ! 119: #define XIEND SZFLAG + SZADDR ! 120: #define XIFMT 2*SZFLAG + SZADDR ! 121: #define XIRLEN 2*SZFLAG + 2*SZADDR ! 122: #define XIRNUM 2*SZFLAG + 2*SZADDR + SZIOINT ! 123: #define XIREC 2*SZFLAG + 2*SZADDR + 2*SZIOINT ! 124: ! 125: /* offsets for OPEN statements */ ! 126: ! 127: #define XFNAME SZFLAG + SZIOINT ! 128: #define XFNAMELEN SZFLAG + SZIOINT + SZADDR ! 129: #define XSTATUS SZFLAG + 2*SZIOINT + SZADDR ! 130: #define XACCESS SZFLAG + 2*SZIOINT + 2*SZADDR ! 131: #define XFORMATTED SZFLAG + 2*SZIOINT + 3*SZADDR ! 132: #define XRECLEN SZFLAG + 2*SZIOINT + 4*SZADDR ! 133: #define XBLANK SZFLAG + 3*SZIOINT + 4*SZADDR ! 134: ! 135: /* offset for CLOSE statement */ ! 136: ! 137: #define XCLSTATUS SZFLAG + SZIOINT ! 138: ! 139: /* offsets for INQUIRE statement */ ! 140: ! 141: #define XFILE SZFLAG + SZIOINT ! 142: #define XFILELEN SZFLAG + SZIOINT + SZADDR ! 143: #define XEXISTS SZFLAG + 2*SZIOINT + SZADDR ! 144: #define XOPEN SZFLAG + 2*SZIOINT + 2*SZADDR ! 145: #define XNUMBER SZFLAG + 2*SZIOINT + 3*SZADDR ! 146: #define XNAMED SZFLAG + 2*SZIOINT + 4*SZADDR ! 147: #define XNAME SZFLAG + 2*SZIOINT + 5*SZADDR ! 148: #define XNAMELEN SZFLAG + 2*SZIOINT + 6*SZADDR ! 149: #define XQACCESS SZFLAG + 3*SZIOINT + 6*SZADDR ! 150: #define XQACCLEN SZFLAG + 3*SZIOINT + 7*SZADDR ! 151: #define XSEQ SZFLAG + 4*SZIOINT + 7*SZADDR ! 152: #define XSEQLEN SZFLAG + 4*SZIOINT + 8*SZADDR ! 153: #define XDIRECT SZFLAG + 5*SZIOINT + 8*SZADDR ! 154: #define XDIRLEN SZFLAG + 5*SZIOINT + 9*SZADDR ! 155: #define XFORM SZFLAG + 6*SZIOINT + 9*SZADDR ! 156: #define XFORMLEN SZFLAG + 6*SZIOINT + 10*SZADDR ! 157: #define XFMTED SZFLAG + 7*SZIOINT + 10*SZADDR ! 158: #define XFMTEDLEN SZFLAG + 7*SZIOINT + 11*SZADDR ! 159: #define XUNFMT SZFLAG + 8*SZIOINT + 11*SZADDR ! 160: #define XUNFMTLEN SZFLAG + 8*SZIOINT + 12*SZADDR ! 161: #define XQRECL SZFLAG + 9*SZIOINT + 12*SZADDR ! 162: #define XNEXTREC SZFLAG + 9*SZIOINT + 13*SZADDR ! 163: #define XQBLANK SZFLAG + 9*SZIOINT + 14*SZADDR ! 164: #define XQBLANKLEN SZFLAG + 9*SZIOINT + 15*SZADDR ! 165: ! 166: fmtstmt(lp) ! 167: register struct Labelblock *lp; ! 168: { ! 169: extern expptr labelfudge(); ! 170: int oldlbl; ! 171: ! 172: if(lp == NULL) ! 173: { ! 174: execerr("unlabeled format statement" , CNULL); ! 175: return(-1); ! 176: } ! 177: if(lp->labtype == LABUNKNOWN) ! 178: { ! 179: oldlbl = lp->labelno; ! 180: lp->labtype = LABFORMAT; ! 181: lp->labelno = newlabel(); ! 182: labelfudge(oldlbl, lp->labelno); ! 183: } ! 184: else if(lp->labtype != LABFORMAT) ! 185: { ! 186: execerr("bad format number", CNULL); ! 187: return(-1); ! 188: } ! 189: return(lp->labelno); ! 190: } ! 191: ! 192: ! 193: ! 194: setfmt(lp) ! 195: struct Labelblock *lp; ! 196: { ! 197: int n; ! 198: char *s, *lexline(); ! 199: ! 200: s = lexline(&n); ! 201: preven(ALILONG); ! 202: prlabel(asmfile, lp->labelno); ! 203: putstr(asmfile, s, n); ! 204: flline(); ! 205: } ! 206: ! 207: ! 208: ! 209: startioctl() ! 210: { ! 211: register int i; ! 212: ! 213: inioctl = YES; ! 214: nioctl = 0; ! 215: ioformatted = UNFORMATTED; ! 216: for(i = 1 ; i<=NIOS ; ++i) ! 217: V(i) = NULL; ! 218: } ! 219: ! 220: ! 221: ! 222: endioctl() ! 223: { ! 224: int i; ! 225: expptr p; ! 226: ! 227: inioctl = NO; ! 228: ! 229: /* set up for error recovery */ ! 230: ! 231: ioerrlab = ioendlab = skiplab = jumplab = 0; ! 232: ! 233: if(p = V(IOSEND)) ! 234: if(ISICON(p)) ! 235: ioendlab = execlab(p->constblock.Const.ci) ->labelno; ! 236: else ! 237: err("bad end= clause"); ! 238: ! 239: if(p = V(IOSERR)) ! 240: if(ISICON(p)) ! 241: ioerrlab = execlab(p->constblock.Const.ci) ->labelno; ! 242: else ! 243: err("bad err= clause"); ! 244: ! 245: if(IOSTP) ! 246: if(IOSTP->tag!=TADDR || ! ISINT(IOSTP->addrblock.vtype) ) ! 247: { ! 248: err("iostat must be an integer variable"); ! 249: frexpr(IOSTP); ! 250: IOSTP = NULL; ! 251: } ! 252: ! 253: if(iostmt == IOREAD) ! 254: { ! 255: if(IOSTP) ! 256: { ! 257: if(ioerrlab && ioendlab && ioerrlab==ioendlab) ! 258: jumplab = ioerrlab; ! 259: else ! 260: skiplab = jumplab = newlabel(); ! 261: } ! 262: else { ! 263: if(ioerrlab && ioendlab && ioerrlab!=ioendlab) ! 264: { ! 265: IOSTP = (expptr) mktemp(TYINT, PNULL); ! 266: skiplab = jumplab = newlabel(); ! 267: } ! 268: else ! 269: jumplab = (ioerrlab ? ioerrlab : ioendlab); ! 270: } ! 271: } ! 272: else if(iostmt == IOWRITE) ! 273: { ! 274: if(IOSTP && !ioerrlab) ! 275: skiplab = jumplab = newlabel(); ! 276: else ! 277: jumplab = ioerrlab; ! 278: } ! 279: else ! 280: jumplab = ioerrlab; ! 281: ! 282: endbit = IOSTP!=NULL || ioendlab!=0; /* for use in startrw() */ ! 283: errbit = IOSTP!=NULL || ioerrlab!=0; ! 284: if(iostmt!=IOREAD && iostmt!=IOWRITE) ! 285: { ! 286: if(ioblkp == NULL) ! 287: ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL); ! 288: ioset(TYIOINT, XERR, ICON(errbit)); ! 289: } ! 290: ! 291: switch(iostmt) ! 292: { ! 293: case IOOPEN: ! 294: dofopen(); ! 295: break; ! 296: ! 297: case IOCLOSE: ! 298: dofclose(); ! 299: break; ! 300: ! 301: case IOINQUIRE: ! 302: dofinquire(); ! 303: break; ! 304: ! 305: case IOBACKSPACE: ! 306: dofmove("f_back"); ! 307: break; ! 308: ! 309: case IOREWIND: ! 310: dofmove("f_rew"); ! 311: break; ! 312: ! 313: case IOENDFILE: ! 314: dofmove("f_end"); ! 315: break; ! 316: ! 317: case IOREAD: ! 318: case IOWRITE: ! 319: startrw(); ! 320: break; ! 321: ! 322: default: ! 323: fatali("impossible iostmt %d", iostmt); ! 324: } ! 325: for(i = 1 ; i<=NIOS ; ++i) ! 326: if(i!=IOSIOSTAT && V(i)!=NULL) ! 327: frexpr(V(i)); ! 328: } ! 329: ! 330: ! 331: ! 332: iocname() ! 333: { ! 334: register int i; ! 335: int found, mask; ! 336: ! 337: found = 0; ! 338: mask = M(iostmt); ! 339: for(i = 1 ; i <= NIOS ; ++i) ! 340: if(toklen==strlen(ioc[i].iocname) && eqn(toklen, token, ioc[i].iocname)) ! 341: if(ioc[i].iotype & mask) ! 342: return(i); ! 343: else found = i; ! 344: if(found) ! 345: errstr("invalid control %s for statement", ioc[found].iocname); ! 346: else ! 347: errstr("unknown iocontrol %s", varstr(toklen, token) ); ! 348: return(IOSBAD); ! 349: } ! 350: ! 351: ! 352: ioclause(n, p) ! 353: register int n; ! 354: register expptr p; ! 355: { ! 356: struct Ioclist *iocp; ! 357: ! 358: ++nioctl; ! 359: if(n == IOSBAD) ! 360: return; ! 361: if(n == IOSPOSITIONAL) ! 362: { ! 363: n = nioctl; ! 364: if (nioctl == IOSFMT) { ! 365: if (iostmt == IOOPEN) { ! 366: n = IOSFILE; ! 367: NOEXT("file= specifier omitted from open"); ! 368: } ! 369: else if (iostmt < IOREAD) ! 370: goto illegal; ! 371: } ! 372: else if(nioctl > IOSFMT) ! 373: { ! 374: illegal: ! 375: err("illegal positional iocontrol"); ! 376: return; ! 377: } ! 378: } ! 379: else if (n == IOSNML) ! 380: n = IOSFMT; ! 381: ! 382: if(p == NULL) ! 383: { ! 384: if(n == IOSUNIT) ! 385: p = (expptr) (iostmt==IOREAD ? IOSTDIN : IOSTDOUT); ! 386: else if(n != IOSFMT) ! 387: { ! 388: err("illegal * iocontrol"); ! 389: return; ! 390: } ! 391: } ! 392: if(n == IOSFMT) ! 393: ioformatted = (p==NULL ? LISTDIRECTED : FORMATTED); ! 394: ! 395: iocp = & ioc[n]; ! 396: if(iocp->iocval == NULL) ! 397: { ! 398: if(n!=IOSFMT && ( n!=IOSUNIT || (p!=NULL && p->headblock.vtype!=TYCHAR) ) ) ! 399: p = fixtype(p); ! 400: iocp->iocval = p; ! 401: } ! 402: else ! 403: errstr("iocontrol %s repeated", iocp->iocname); ! 404: } ! 405: ! 406: /* io list item */ ! 407: ! 408: doio(list) ! 409: chainp list; ! 410: { ! 411: expptr call0(); ! 412: ! 413: if(ioformatted == NAMEDIRECTED) ! 414: { ! 415: if(list) ! 416: err("no I/O list allowed in NAMELIST read/write"); ! 417: } ! 418: else ! 419: { ! 420: doiolist(list); ! 421: ioroutine[0] = 'e'; ! 422: putiocall( call0(TYINT, ioroutine) ); ! 423: } ! 424: } ! 425: ! 426: ! 427: ! 428: ! 429: ! 430: LOCAL doiolist(p0) ! 431: chainp p0; ! 432: { ! 433: chainp p; ! 434: register tagptr q; ! 435: register expptr qe; ! 436: register Namep qn; ! 437: Addrp tp, mkscalar(); ! 438: int range; ! 439: ! 440: for (p = p0 ; p ; p = p->nextp) ! 441: { ! 442: q = p->datap; ! 443: if(q->tag == TIMPLDO) ! 444: { ! 445: exdo(range=newlabel(), q->impldoblock.impdospec); ! 446: doiolist(q->impldoblock.datalist); ! 447: enddo(range); ! 448: free( (charptr) q); ! 449: } ! 450: else { ! 451: if(q->tag==TPRIM && q->primblock.argsp==NULL ! 452: && q->primblock.namep->vdim!=NULL) ! 453: { ! 454: vardcl(qn = q->primblock.namep); ! 455: if(qn->vdim->nelt) ! 456: putio( fixtype(cpexpr(qn->vdim->nelt)), ! 457: mkscalar(qn) ); ! 458: else ! 459: err("attempt to i/o array of unknown size"); ! 460: } ! 461: else if(q->tag==TPRIM && q->primblock.argsp==NULL && ! 462: (qe = (expptr) memversion(q->primblock.namep)) ) ! 463: putio(ICON(1),qe); ! 464: else if( (qe = fixtype(cpexpr(q)))->tag==TADDR) ! 465: putio(ICON(1), qe); ! 466: else if(qe->headblock.vtype != TYERROR) ! 467: { ! 468: if(iostmt == IOWRITE) ! 469: { ! 470: ftnint lencat(); ! 471: expptr qvl; ! 472: qvl = NULL; ! 473: if( ISCHAR(qe) ) ! 474: { ! 475: qvl = (expptr) ! 476: cpexpr(qe->headblock.vleng); ! 477: tp = mktemp(qe->headblock.vtype, ! 478: ICON(lencat(qe))); ! 479: } ! 480: else ! 481: tp = mktemp(qe->headblock.vtype, ! 482: qe->headblock.vleng); ! 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: if( ISCONST(addr) ) ! 522: addr = (expptr) putconst(addr); ! 523: addr->headblock.vtype = TYCHAR; ! 524: addr->headblock.vleng = ICON( typesize[type] ); ! 525: } ! 526: ! 527: nelt = fixtype( mkconv(TYLENG,nelt) ); ! 528: if(ioformatted == LISTDIRECTED) ! 529: q = call3(TYINT, "do_lio", mkconv(TYLONG, ICON(type)), nelt, addr); ! 530: else ! 531: q = call2(TYINT, (ioformatted==FORMATTED ? "do_fio" : "do_uio"), ! 532: nelt, addr); ! 533: putiocall(q); ! 534: } ! 535: ! 536: ! 537: ! 538: ! 539: endio() ! 540: { ! 541: if(skiplab) ! 542: { ! 543: putlabel(skiplab); ! 544: if(ioendlab) ! 545: putif( mkexpr(OPGE, cpexpr(IOSTP), ICON(0)), ioendlab); ! 546: if(ioerrlab) ! 547: putif( mkexpr( ( (iostmt==IOREAD||iostmt==IOWRITE) ? OPLE : OPEQ), ! 548: cpexpr(IOSTP), ICON(0)) , ioerrlab); ! 549: } ! 550: if(IOSTP) ! 551: frexpr(IOSTP); ! 552: } ! 553: ! 554: ! 555: ! 556: LOCAL putiocall(q) ! 557: register expptr q; ! 558: { ! 559: if(IOSTP) ! 560: { ! 561: q->headblock.vtype = TYINT; ! 562: q = fixexpr( mkexpr(OPASSIGN, cpexpr(IOSTP), q)); ! 563: } ! 564: ! 565: if(jumplab) ! 566: putif( mkexpr(OPEQ, q, ICON(0) ), jumplab); ! 567: else ! 568: putexpr(q); ! 569: } ! 570: ! 571: startrw() ! 572: { ! 573: register expptr p; ! 574: register Namep np; ! 575: register Addrp unitp, fmtp, recp, tioblkp; ! 576: register expptr nump; ! 577: Addrp mkscalar(); ! 578: expptr mkaddcon(); ! 579: int k; ! 580: flag intfile, sequential, ok, varfmt; ! 581: ! 582: /* First look at all the parameters and determine what is to be done */ ! 583: ! 584: ok = YES; ! 585: statstruct = YES; ! 586: ! 587: intfile = NO; ! 588: if(p = V(IOSUNIT)) ! 589: { ! 590: if( ISINT(p->headblock.vtype) ) ! 591: unitp = (Addrp) cpexpr(p); ! 592: else if(p->headblock.vtype == TYCHAR) ! 593: { ! 594: intfile = YES; ! 595: if(p->tag==TPRIM && p->primblock.argsp==NULL && ! 596: (np = p->primblock.namep)->vdim!=NULL) ! 597: { ! 598: vardcl(np); ! 599: if(np->vdim->nelt) ! 600: { ! 601: nump = (expptr) cpexpr(np->vdim->nelt); ! 602: if( ! ISCONST(nump) ) ! 603: statstruct = NO; ! 604: } ! 605: else ! 606: { ! 607: err("attempt to use internal unit array of unknown size"); ! 608: ok = NO; ! 609: nump = ICON(1); ! 610: } ! 611: unitp = mkscalar(np); ! 612: } ! 613: else { ! 614: nump = ICON(1); ! 615: unitp = (Addrp /*pjw */) fixtype(cpexpr(p)); ! 616: } ! 617: if(! isstatic(unitp) ) ! 618: statstruct = NO; ! 619: } ! 620: } ! 621: else ! 622: { ! 623: err("bad unit specifier"); ! 624: ok = NO; ! 625: } ! 626: ! 627: sequential = YES; ! 628: if(p = V(IOSREC)) ! 629: if( ISINT(p->headblock.vtype) ) ! 630: { ! 631: recp = (Addrp) cpexpr(p); ! 632: sequential = NO; ! 633: } ! 634: else { ! 635: err("bad REC= clause"); ! 636: ok = NO; ! 637: } ! 638: else ! 639: recp = NULL; ! 640: ! 641: ! 642: varfmt = YES; ! 643: fmtp = NULL; ! 644: if(p = V(IOSFMT)) ! 645: { ! 646: if(p->tag==TPRIM && p->primblock.argsp==NULL) ! 647: { ! 648: np = p->primblock.namep; ! 649: if(np->vclass == CLNAMELIST) ! 650: { ! 651: ioformatted = NAMEDIRECTED; ! 652: fmtp = (Addrp) fixtype(p); ! 653: V(IOSFMT) = (expptr)fmtp; ! 654: goto endfmt; ! 655: } ! 656: vardcl(np); ! 657: if(np->vdim) ! 658: { ! 659: if( ! ONEOF(np->vstg, MSKSTATIC) ) ! 660: statstruct = NO; ! 661: fmtp = mkscalar(np); ! 662: goto endfmt; ! 663: } ! 664: if( ISINT(np->vtype) ) /* ASSIGNed label */ ! 665: { ! 666: statstruct = NO; ! 667: varfmt = NO; ! 668: fmtp = (Addrp) fixtype(p); ! 669: if (!(bugwarn & 2)) { ! 670: V(IOSFMT) = 0; ! 671: if (bugwarn) ! 672: warnb("old f77 died here"); ! 673: } ! 674: goto endfmt; ! 675: } ! 676: } ! 677: p = V(IOSFMT) = fixtype(p); ! 678: if(p->headblock.vtype == TYCHAR) ! 679: { ! 680: if( ! isstatic(p) ) ! 681: statstruct = NO; ! 682: fmtp = (Addrp) cpexpr(p); ! 683: } ! 684: else if( ISICON(p) ) ! 685: { ! 686: if( (k = fmtstmt( mklabel(p->constblock.Const.ci) )) > 0 ) ! 687: { ! 688: fmtp = (Addrp) mkaddcon(k); ! 689: varfmt = NO; ! 690: } ! 691: else ! 692: ioformatted = UNFORMATTED; ! 693: } ! 694: else { ! 695: err("bad format descriptor"); ! 696: ioformatted = UNFORMATTED; ! 697: ok = NO; ! 698: } ! 699: } ! 700: else ! 701: fmtp = NULL; ! 702: ! 703: endfmt: ! 704: if(intfile) { ! 705: if (ioformatted==UNFORMATTED) { ! 706: err("unformatted internal I/O not allowed"); ! 707: ok = NO; ! 708: } ! 709: if (recp) { ! 710: err("direct internal I/O not allowed"); ! 711: ok = NO; ! 712: } ! 713: } ! 714: if(!sequential && ioformatted==LISTDIRECTED) ! 715: { ! 716: err("direct list-directed I/O not allowed"); ! 717: ok = NO; ! 718: } ! 719: if(!sequential && ioformatted==NAMEDIRECTED) ! 720: { ! 721: err("direct namelist I/O not allowed"); ! 722: ok = NO; ! 723: } ! 724: ! 725: if( ! ok ) ! 726: return; ! 727: ! 728: /* ! 729: Now put out the I/O structure, statically if all the clauses ! 730: are constants, dynamically otherwise ! 731: */ ! 732: ! 733: if(statstruct) ! 734: { ! 735: tioblkp = ioblkp; ! 736: ioblkp = ALLOC(Addrblock); ! 737: ioblkp->tag = TADDR; ! 738: ioblkp->vtype = TYIOINT; ! 739: ioblkp->vclass = CLVAR; ! 740: ioblkp->vstg = STGINIT; ! 741: ioblkp->memno = ++lastvarno; ! 742: ioblkp->memoffset = ICON(0); ! 743: blklen = (intfile ? XIREC+SZIOINT : ! 744: (sequential ? XFMT+SZADDR : XRNUM+SZIOINT) ); ! 745: } ! 746: else if(ioblkp == NULL) ! 747: ioblkp = autovar( (MAXIO+SZIOINT-1)/SZIOINT , TYIOINT, PNULL); ! 748: ! 749: ioset(TYIOINT, XERR, ICON(errbit)); ! 750: if(iostmt == IOREAD) ! 751: ioset(TYIOINT, (intfile ? XIEND : XEND), ICON(endbit) ); ! 752: ! 753: if(intfile) ! 754: { ! 755: ioset(TYIOINT, XIRNUM, nump); ! 756: ioset(TYIOINT, XIRLEN, cpexpr(unitp->vleng) ); ! 757: ioseta(XIUNIT, unitp); ! 758: } ! 759: else ! 760: ioset(TYIOINT, XUNIT, (expptr) unitp); ! 761: ! 762: if(recp) ! 763: ioset(TYIOINT, (intfile ? XIREC : XREC) , (expptr) recp); ! 764: ! 765: if(varfmt) ! 766: ioseta( intfile ? XIFMT : XFMT , fmtp); ! 767: else ! 768: ioset(TYADDR, intfile ? XIFMT : XFMT, (expptr) fmtp); ! 769: ! 770: ioroutine[0] = 's'; ! 771: ioroutine[1] = '_'; ! 772: ioroutine[2] = (iostmt==IOREAD ? 'r' : 'w'); ! 773: ioroutine[3] = (sequential ? 's' : 'd'); ! 774: ioroutine[4] = "ufln" [ioformatted]; ! 775: ioroutine[5] = (intfile ? 'i' : 'e'); ! 776: ioroutine[6] = '\0'; ! 777: ! 778: putiocall( call1(TYINT, ioroutine, cpexpr(ioblkp) )); ! 779: ! 780: if(statstruct) ! 781: { ! 782: frexpr(ioblkp); ! 783: ioblkp = tioblkp; ! 784: statstruct = NO; ! 785: } ! 786: } ! 787: ! 788: ! 789: ! 790: LOCAL dofopen() ! 791: { ! 792: register expptr p; ! 793: ! 794: if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) ) ! 795: ioset(TYIOINT, XUNIT, cpexpr(p) ); ! 796: else ! 797: err("bad unit in open"); ! 798: if( (p = V(IOSFILE)) ) ! 799: if(p->headblock.vtype == TYCHAR) ! 800: ioset(TYIOINT, XFNAMELEN, cpexpr(p->headblock.vleng) ); ! 801: else ! 802: err("bad file in open"); ! 803: ! 804: iosetc(XFNAME, p); ! 805: ! 806: if(p = V(IOSRECL)) ! 807: if( ISINT(p->headblock.vtype) ) ! 808: ioset(TYIOINT, XRECLEN, cpexpr(p) ); ! 809: else ! 810: err("bad recl"); ! 811: else ! 812: ioset(TYIOINT, XRECLEN, ICON(0) ); ! 813: ! 814: iosetc(XSTATUS, V(IOSSTATUS)); ! 815: iosetc(XACCESS, V(IOSACCESS)); ! 816: iosetc(XFORMATTED, V(IOSFORM)); ! 817: iosetc(XBLANK, V(IOSBLANK)); ! 818: ! 819: putiocall( call1(TYINT, "f_open", cpexpr(ioblkp) )); ! 820: } ! 821: ! 822: ! 823: LOCAL dofclose() ! 824: { ! 825: register expptr p; ! 826: ! 827: if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) ) ! 828: { ! 829: ioset(TYIOINT, XUNIT, cpexpr(p) ); ! 830: iosetc(XCLSTATUS, V(IOSSTATUS)); ! 831: putiocall( call1(TYINT, "f_clos", cpexpr(ioblkp)) ); ! 832: } ! 833: else ! 834: err("bad unit in close statement"); ! 835: } ! 836: ! 837: ! 838: LOCAL dofinquire() ! 839: { ! 840: register expptr p; ! 841: if(p = V(IOSUNIT)) ! 842: { ! 843: if( V(IOSFILE) ) ! 844: err("inquire by unit or by file, not both"); ! 845: ioset(TYIOINT, XUNIT, cpexpr(p) ); ! 846: } ! 847: else if( ! V(IOSFILE) ) ! 848: err("must inquire by unit or by file"); ! 849: iosetlc(IOSFILE, XFILE, XFILELEN); ! 850: iosetip(IOSEXISTS, XEXISTS); ! 851: iosetip(IOSOPENED, XOPEN); ! 852: iosetip(IOSNUMBER, XNUMBER); ! 853: iosetip(IOSNAMED, XNAMED); ! 854: iosetlc(IOSNAME, XNAME, XNAMELEN); ! 855: iosetlc(IOSACCESS, XQACCESS, XQACCLEN); ! 856: iosetlc(IOSSEQUENTIAL, XSEQ, XSEQLEN); ! 857: iosetlc(IOSDIRECT, XDIRECT, XDIRLEN); ! 858: iosetlc(IOSFORM, XFORM, XFORMLEN); ! 859: iosetlc(IOSFORMATTED, XFMTED, XFMTEDLEN); ! 860: iosetlc(IOSUNFORMATTED, XUNFMT, XUNFMTLEN); ! 861: iosetip(IOSRECL, XQRECL); ! 862: iosetip(IOSNEXTREC, XNEXTREC); ! 863: iosetlc(IOSBLANK, XQBLANK, XQBLANKLEN); ! 864: ! 865: putiocall( call1(TYINT, "f_inqu", cpexpr(ioblkp) )); ! 866: } ! 867: ! 868: ! 869: ! 870: LOCAL dofmove(subname) ! 871: char *subname; ! 872: { ! 873: register expptr p; ! 874: ! 875: if( (p = V(IOSUNIT)) && ISINT(p->headblock.vtype) ) ! 876: { ! 877: ioset(TYIOINT, XUNIT, cpexpr(p) ); ! 878: putiocall( call1(TYINT, subname, cpexpr(ioblkp) )); ! 879: } ! 880: else ! 881: err("bad unit in I/O motion statement"); ! 882: } ! 883: ! 884: ! 885: ! 886: LOCAL ioset(type, offset, p) ! 887: int type, offset; ! 888: register expptr p; ! 889: { ! 890: register Addrp q; ! 891: ! 892: q = (Addrp) cpexpr(ioblkp); ! 893: q->vtype = type; ! 894: q->memoffset = fixtype( mkexpr(OPPLUS, q->memoffset, ICON(offset)) ); ! 895: if(statstruct && ISCONST(p)) ! 896: { ! 897: setdata(q, p, 0L, blklen); ! 898: frexpr(q); ! 899: frexpr(p); ! 900: } ! 901: else ! 902: puteq(q, p); ! 903: } ! 904: ! 905: ! 906: ! 907: ! 908: LOCAL iosetc(offset, p) ! 909: int offset; ! 910: register expptr p; ! 911: { ! 912: if(p == NULL) ! 913: ioset(TYADDR, offset, ICON(0) ); ! 914: else if(p->headblock.vtype == TYCHAR) ! 915: ioset(TYADDR, offset, addrof(cpexpr(p) )); ! 916: else ! 917: err("non-character control clause"); ! 918: } ! 919: ! 920: ! 921: ! 922: LOCAL ioseta(offset, p) ! 923: int offset; ! 924: register Addrp p; ! 925: { ! 926: char *dataname(); ! 927: ! 928: if(statstruct) ! 929: { ! 930: dataline(dataname(STGINIT,ioblkp->memno), (ftnint) offset, ! 931: blklen, TYADDR); ! 932: if(p) ! 933: praddr(initfile, p->vstg, p->memno, ! 934: p->memoffset->constblock.Const.ci); ! 935: else ! 936: praddr(initfile, STGNULL, 0, (ftnint) 0); ! 937: } ! 938: else ! 939: ioset(TYADDR, offset, p ? addrof(p) : ICON(0) ); ! 940: } ! 941: ! 942: ! 943: ! 944: ! 945: LOCAL iosetip(i, offset) ! 946: int i, offset; ! 947: { ! 948: register expptr p; ! 949: ! 950: if(p = V(i)) ! 951: if(p->tag==TADDR && ! 952: ONEOF(p->addrblock.vtype, M(TYLONG)|M(TYLOGICAL)) ) ! 953: ioset(TYADDR, offset, addrof(cpexpr(p)) ); ! 954: else ! 955: errstr("impossible inquire parameter %s", ioc[i].iocname); ! 956: else ! 957: ioset(TYADDR, offset, ICON(0) ); ! 958: } ! 959: ! 960: ! 961: ! 962: LOCAL iosetlc(i, offp, offl) ! 963: int i, offp, offl; ! 964: { ! 965: register expptr p; ! 966: if( (p = V(i)) && p->headblock.vtype==TYCHAR) ! 967: ioset(TYIOINT, offl, cpexpr(p->headblock.vleng) ); ! 968: iosetc(offp, p); ! 969: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.