Annotation of 43BSD/usr.bin/f77/src/f77pass1/io.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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