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