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