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