Annotation of 42BSD/old/f77/io.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.