Annotation of researchv10no/cmd/f2c/equiv.c, revision 1.1

1.1     ! root        1: /****************************************************************
        !             2: Copyright 1990, 1993 by AT&T Bell Laboratories and Bellcore.
        !             3: 
        !             4: Permission to use, copy, modify, and distribute this software
        !             5: and its documentation for any purpose and without fee is hereby
        !             6: granted, provided that the above copyright notice appear in all
        !             7: copies and that both that the copyright notice and this
        !             8: permission notice and warranty disclaimer appear in supporting
        !             9: documentation, and that the names of AT&T Bell Laboratories or
        !            10: Bellcore or any of their entities not be used in advertising or
        !            11: publicity pertaining to distribution of the software without
        !            12: specific, written prior permission.
        !            13: 
        !            14: AT&T and Bellcore disclaim all warranties with regard to this
        !            15: software, including all implied warranties of merchantability
        !            16: and fitness.  In no event shall AT&T or Bellcore be liable for
        !            17: any special, indirect or consequential damages or any damages
        !            18: whatsoever resulting from loss of use, data or profits, whether
        !            19: in an action of contract, negligence or other tortious action,
        !            20: arising out of or in connection with the use or performance of
        !            21: this software.
        !            22: ****************************************************************/
        !            23: 
        !            24: #include "defs.h"
        !            25: 
        !            26: LOCAL eqvcommon(), eqveqv(), nsubs();
        !            27: 
        !            28: /* ROUTINES RELATED TO EQUIVALENCE CLASS PROCESSING */
        !            29: 
        !            30: /* called at end of declarations section to process chains
        !            31:    created by EQUIVALENCE statements
        !            32:  */
        !            33: doequiv()
        !            34: {
        !            35:        register int i;
        !            36:        int inequiv;                    /* True if one namep occurs in
        !            37:                                           several EQUIV declarations */
        !            38:        int comno;              /* Index into Extsym table of the last
        !            39:                                   COMMON block seen (implicitly assuming
        !            40:                                   that only one will be given) */
        !            41:        int ovarno;
        !            42:        ftnint comoffset;       /* Index into the COMMON block */
        !            43:        ftnint offset;          /* Offset from array base */
        !            44:        ftnint leng;
        !            45:        register struct Equivblock *equivdecl;
        !            46:        register struct Eqvchain *q;
        !            47:        struct Primblock *primp;
        !            48:        register Namep np;
        !            49:        int k, k1, ns, pref, t;
        !            50:        chainp cp;
        !            51:        extern int type_pref[];
        !            52:        char *s;
        !            53: 
        !            54:        for(i = 0 ; i < nequiv ; ++i)
        !            55:        {
        !            56: 
        !            57: /* Handle each equivalence declaration */
        !            58: 
        !            59:                equivdecl = &eqvclass[i];
        !            60:                equivdecl->eqvbottom = equivdecl->eqvtop = 0;
        !            61:                comno = -1;
        !            62: 
        !            63: 
        !            64: 
        !            65:                for(q = equivdecl->equivs ; q ; q = q->eqvnextp)
        !            66:                {
        !            67:                        offset = 0;
        !            68:                        primp = q->eqvitem.eqvlhs;
        !            69:                        vardcl(np = primp->namep);
        !            70:                        if(primp->argsp || primp->fcharp)
        !            71:                        {
        !            72:                                expptr offp, suboffset();
        !            73: 
        !            74: /* Pad ones onto the end of an array declaration when needed */
        !            75: 
        !            76:                                if(np->vdim!=NULL && np->vdim->ndim>1 &&
        !            77:                                    nsubs(primp->argsp)==1 )
        !            78:                                {
        !            79:                                        if(! ftn66flag)
        !            80:                                                warni
        !            81:                        ("1-dim subscript in EQUIVALENCE, %d-dim declared",
        !            82:                                                    np -> vdim -> ndim);
        !            83:                                        cp = NULL;
        !            84:                                        ns = np->vdim->ndim;
        !            85:                                        while(--ns > 0)
        !            86:                                                cp = mkchain((char *)ICON(1), cp);
        !            87:                                        primp->argsp->listp->nextp = cp;
        !            88:                                }
        !            89: 
        !            90:                                offp = suboffset(primp);
        !            91:                                if(ISICON(offp))
        !            92:                                        offset = offp->constblock.Const.ci;
        !            93:                                else    {
        !            94:                                        dclerr
        !            95:                        ("nonconstant subscript in equivalence ",
        !            96:                                            np);
        !            97:                                        np = NULL;
        !            98:                                }
        !            99:                                frexpr(offp);
        !           100:                        }
        !           101: 
        !           102: /* Free up the primblock, since we now have a hash table (Namep) entry */
        !           103: 
        !           104:                        frexpr((expptr)primp);
        !           105: 
        !           106:                        if(np && (leng = iarrlen(np))<0)
        !           107:                        {
        !           108:                                dclerr("adjustable in equivalence", np);
        !           109:                                np = NULL;
        !           110:                        }
        !           111: 
        !           112:                        if(np) switch(np->vstg)
        !           113:                        {
        !           114:                        case STGUNKNOWN:
        !           115:                        case STGBSS:
        !           116:                        case STGEQUIV:
        !           117:                                if (in_vector(np->cvarname, st_fields,
        !           118:                                                n_st_fields) >= 0) {
        !           119:                                        k = strlen(np->cvarname);
        !           120:                                        strcpy(s = mem(k+2,0), np->cvarname);
        !           121:                                        s[k] = '_';
        !           122:                                        s[k+1] = 0;
        !           123:                                        np->cvarname = s;
        !           124:                                        }
        !           125:                                break;
        !           126: 
        !           127:                        case STGCOMMON:
        !           128: 
        !           129: /* The code assumes that all COMMON references in a given EQUIVALENCE will
        !           130:    be to the same COMMON block, and will all be consistent */
        !           131: 
        !           132:                                comno = np->vardesc.varno;
        !           133:                                comoffset = np->voffset + offset;
        !           134:                                break;
        !           135: 
        !           136:                        default:
        !           137:                                dclerr("bad storage class in equivalence", np);
        !           138:                                np = NULL;
        !           139:                                break;
        !           140:                        }
        !           141: 
        !           142:                        if(np)
        !           143:                        {
        !           144:                                q->eqvoffset = offset;
        !           145: 
        !           146: /* eqvbottom   gets the largest difference between the array base address
        !           147:    and the address specified in the EQUIV declaration */
        !           148: 
        !           149:                                equivdecl->eqvbottom =
        !           150:                                    lmin(equivdecl->eqvbottom, -offset);
        !           151: 
        !           152: /* eqvtop   gets the largest difference between the end of the array and
        !           153:    the address given in the EQUIVALENCE */
        !           154: 
        !           155:                                equivdecl->eqvtop =
        !           156:                                    lmax(equivdecl->eqvtop, leng-offset);
        !           157:                        }
        !           158:                        q->eqvitem.eqvname = np;
        !           159:                }
        !           160: 
        !           161: /* Now all equivalenced variables are in the hash table with the proper
        !           162:    offset, and   eqvtop and eqvbottom   are set. */
        !           163: 
        !           164:                if(comno >= 0)
        !           165: 
        !           166: /* Get rid of all STGEQUIVS, they will be mapped onto STGCOMMON variables
        !           167:    */
        !           168: 
        !           169:                        eqvcommon(equivdecl, comno, comoffset);
        !           170:                else for(q = equivdecl->equivs ; q ; q = q->eqvnextp)
        !           171:                {
        !           172:                        if(np = q->eqvitem.eqvname)
        !           173:                        {
        !           174:                                inequiv = NO;
        !           175:                                if(np->vstg==STGEQUIV)
        !           176:                                        if( (ovarno = np->vardesc.varno) == i)
        !           177:                                        {
        !           178: 
        !           179: /* Can't EQUIV different elements of the same array */
        !           180: 
        !           181:                                                if(np->voffset + q->eqvoffset != 0)
        !           182:                                                        dclerr
        !           183:                        ("inconsistent equivalence", np);
        !           184:                                        }
        !           185:                                        else    {
        !           186:                                                offset = np->voffset;
        !           187:                                                inequiv = YES;
        !           188:                                        }
        !           189: 
        !           190:                                np->vstg = STGEQUIV;
        !           191:                                np->vardesc.varno = i;
        !           192:                                np->voffset = - q->eqvoffset;
        !           193: 
        !           194:                                if(inequiv)
        !           195: 
        !           196: /* Combine 2 equivalence declarations */
        !           197: 
        !           198:                                        eqveqv(i, ovarno, q->eqvoffset + offset);
        !           199:                        }
        !           200:                }
        !           201:        }
        !           202: 
        !           203: /* Now each equivalence declaration is distinct (all connections have been
        !           204:    merged in eqveqv()), and some may be empty. */
        !           205: 
        !           206:        for(i = 0 ; i < nequiv ; ++i)
        !           207:        {
        !           208:                equivdecl = & eqvclass[i];
        !           209:                if(equivdecl->eqvbottom!=0 || equivdecl->eqvtop!=0) {
        !           210: 
        !           211: /* a live chain */
        !           212: 
        !           213:                        k = TYCHAR;
        !           214:                        pref = 1;
        !           215:                        for(q = equivdecl->equivs ; q; q = q->eqvnextp)
        !           216:                            if (np = q->eqvitem.eqvname){
        !           217:                                np->voffset -= equivdecl->eqvbottom;
        !           218:                                t = typealign[k1 = np->vtype];
        !           219:                                if (pref < type_pref[k1]) {
        !           220:                                        k = k1;
        !           221:                                        pref = type_pref[k1];
        !           222:                                        }
        !           223:                                if(np->voffset % t != 0) {
        !           224:                                        dclerr("bad alignment forced by equivalence", np);
        !           225:                                        --nerr; /* don't give bad return code for this */
        !           226:                                        }
        !           227:                                }
        !           228:                        equivdecl->eqvtype = k;
        !           229:                }
        !           230:                freqchain(equivdecl);
        !           231:        }
        !           232: }
        !           233: 
        !           234: 
        !           235: 
        !           236: 
        !           237: 
        !           238: /* put equivalence chain p at common block comno + comoffset */
        !           239: 
        !           240: LOCAL eqvcommon(p, comno, comoffset)
        !           241: struct Equivblock *p;
        !           242: int comno;
        !           243: ftnint comoffset;
        !           244: {
        !           245:        int ovarno;
        !           246:        ftnint k, offq;
        !           247:        register Namep np;
        !           248:        register struct Eqvchain *q;
        !           249: 
        !           250:        if(comoffset + p->eqvbottom < 0)
        !           251:        {
        !           252:                errstr("attempt to extend common %s backward",
        !           253:                    extsymtab[comno].fextname);
        !           254:                freqchain(p);
        !           255:                return;
        !           256:        }
        !           257: 
        !           258:        if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)
        !           259:                extsymtab[comno].extleng = k;
        !           260: 
        !           261: 
        !           262:        for(q = p->equivs ; q ; q = q->eqvnextp)
        !           263:                if(np = q->eqvitem.eqvname)
        !           264:                {
        !           265:                        switch(np->vstg)
        !           266:                        {
        !           267:                        case STGUNKNOWN:
        !           268:                        case STGBSS:
        !           269:                                np->vstg = STGCOMMON;
        !           270:                                np->vcommequiv = 1;
        !           271:                                np->vardesc.varno = comno;
        !           272: 
        !           273: /* np -> voffset   will point to the base of the array */
        !           274: 
        !           275:                                np->voffset = comoffset - q->eqvoffset;
        !           276:                                break;
        !           277: 
        !           278:                        case STGEQUIV:
        !           279:                                ovarno = np->vardesc.varno;
        !           280: 
        !           281: /* offq   will point to the current element, even if it's in an array */
        !           282: 
        !           283:                                offq = comoffset - q->eqvoffset - np->voffset;
        !           284:                                np->vstg = STGCOMMON;
        !           285:                                np->vcommequiv = 1;
        !           286:                                np->vardesc.varno = comno;
        !           287: 
        !           288: /* np -> voffset   will point to the base of the array */
        !           289: 
        !           290:                                np->voffset += offq;
        !           291:                                if(ovarno != (p - eqvclass))
        !           292:                                        eqvcommon(&eqvclass[ovarno], comno, offq);
        !           293:                                break;
        !           294: 
        !           295:                        case STGCOMMON:
        !           296:                                if(comno != np->vardesc.varno ||
        !           297:                                    comoffset != np->voffset+q->eqvoffset)
        !           298:                                        dclerr("inconsistent common usage", np);
        !           299:                                break;
        !           300: 
        !           301: 
        !           302:                        default:
        !           303:                                badstg("eqvcommon", np->vstg);
        !           304:                        }
        !           305:                }
        !           306: 
        !           307:        freqchain(p);
        !           308:        p->eqvbottom = p->eqvtop = 0;
        !           309: }
        !           310: 
        !           311: 
        !           312: /* Move all items on ovarno chain to the front of   nvarno   chain.
        !           313:  * adjust offsets of ovarno elements and top and bottom of nvarno chain
        !           314:  */
        !           315: 
        !           316: LOCAL eqveqv(nvarno, ovarno, delta)
        !           317: int ovarno, nvarno;
        !           318: ftnint delta;
        !           319: {
        !           320:        register struct Equivblock *neweqv, *oldeqv;
        !           321:        register Namep np;
        !           322:        struct Eqvchain *q, *q1;
        !           323: 
        !           324:        neweqv = eqvclass + nvarno;
        !           325:        oldeqv = eqvclass + ovarno;
        !           326:        neweqv->eqvbottom = lmin(neweqv->eqvbottom, oldeqv->eqvbottom - delta);
        !           327:        neweqv->eqvtop = lmax(neweqv->eqvtop, oldeqv->eqvtop - delta);
        !           328:        oldeqv->eqvbottom = oldeqv->eqvtop = 0;
        !           329: 
        !           330:        for(q = oldeqv->equivs ; q ; q = q1)
        !           331:        {
        !           332:                q1 = q->eqvnextp;
        !           333:                if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)
        !           334:                {
        !           335:                        q->eqvnextp = neweqv->equivs;
        !           336:                        neweqv->equivs = q;
        !           337:                        q->eqvoffset += delta;
        !           338:                        np->vardesc.varno = nvarno;
        !           339:                        np->voffset -= delta;
        !           340:                }
        !           341:                else    free( (charptr) q);
        !           342:        }
        !           343:        oldeqv->equivs = NULL;
        !           344: }
        !           345: 
        !           346: 
        !           347: 
        !           348: 
        !           349: freqchain(p)
        !           350: register struct Equivblock *p;
        !           351: {
        !           352:        register struct Eqvchain *q, *oq;
        !           353: 
        !           354:        for(q = p->equivs ; q ; q = oq)
        !           355:        {
        !           356:                oq = q->eqvnextp;
        !           357:                free( (charptr) q);
        !           358:        }
        !           359:        p->equivs = NULL;
        !           360: }
        !           361: 
        !           362: 
        !           363: 
        !           364: 
        !           365: 
        !           366: /* nsubs -- number of subscripts in this arglist (just the length of the
        !           367:    list) */
        !           368: 
        !           369: LOCAL nsubs(p)
        !           370: register struct Listblock *p;
        !           371: {
        !           372:        register int n;
        !           373:        register chainp q;
        !           374: 
        !           375:        n = 0;
        !           376:        if(p)
        !           377:                for(q = p->listp ; q ; q = q->nextp)
        !           378:                        ++n;
        !           379: 
        !           380:        return(n);
        !           381: }

unix.superglobalmegacorp.com

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