Annotation of researchv10no/cmd/f2c/misc.c, revision 1.1.1.1

1.1       root        1: /****************************************************************
                      2: Copyright 1990, 1992, 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: int oneof_stg (name, stg, mask)
                     27:  Namep name;
                     28:  int stg, mask;
                     29: {
                     30:        if (stg == STGCOMMON && name) {
                     31:                if ((mask & M(STGEQUIV)))
                     32:                        return name->vcommequiv;
                     33:                if ((mask & M(STGCOMMON)))
                     34:                        return !name->vcommequiv;
                     35:                }
                     36:        return ONEOF(stg, mask);
                     37:        }
                     38: 
                     39: 
                     40: /* op_assign -- given a binary opcode, return the associated assignment
                     41:    operator */
                     42: 
                     43: int op_assign (opcode)
                     44: int opcode;
                     45: {
                     46:     int retval = -1;
                     47: 
                     48:     switch (opcode) {
                     49:         case OPPLUS: retval = OPPLUSEQ; break;
                     50:        case OPMINUS: retval = OPMINUSEQ; break;
                     51:        case OPSTAR: retval = OPSTAREQ; break;
                     52:        case OPSLASH: retval = OPSLASHEQ; break;
                     53:        case OPMOD: retval = OPMODEQ; break;
                     54:        case OPLSHIFT: retval = OPLSHIFTEQ; break;
                     55:        case OPRSHIFT: retval = OPRSHIFTEQ; break;
                     56:        case OPBITAND: retval = OPBITANDEQ; break;
                     57:        case OPBITXOR: retval = OPBITXOREQ; break;
                     58:        case OPBITOR: retval = OPBITOREQ; break;
                     59:        default:
                     60:            erri ("op_assign:  bad opcode '%d'", opcode);
                     61:            break;
                     62:     } /* switch */
                     63: 
                     64:     return retval;
                     65: } /* op_assign */
                     66: 
                     67: 
                     68:  char *
                     69: Alloc(n)       /* error-checking version of malloc */
                     70:                /* ckalloc initializes memory to 0; Alloc does not */
                     71:  int n;
                     72: {
                     73:        char errbuf[32];
                     74:        register char *rv;
                     75: 
                     76:        rv = malloc(n);
                     77:        if (!rv) {
                     78:                sprintf(errbuf, "malloc(%d) failure!", n);
                     79:                Fatal(errbuf);
                     80:                }
                     81:        return rv;
                     82:        }
                     83: 
                     84: 
                     85: cpn(n, a, b)
                     86: register int n;
                     87: register char *a, *b;
                     88: {
                     89:        while(--n >= 0)
                     90:                *b++ = *a++;
                     91: }
                     92: 
                     93: 
                     94: 
                     95: eqn(n, a, b)
                     96: register int n;
                     97: register char *a, *b;
                     98: {
                     99:        while(--n >= 0)
                    100:                if(*a++ != *b++)
                    101:                        return(NO);
                    102:        return(YES);
                    103: }
                    104: 
                    105: 
                    106: 
                    107: 
                    108: 
                    109: 
                    110: 
                    111: cmpstr(a, b, la, lb)   /* compare two strings */
                    112: register char *a, *b;
                    113: ftnint la, lb;
                    114: {
                    115:        register char *aend, *bend;
                    116:        aend = a + la;
                    117:        bend = b + lb;
                    118: 
                    119: 
                    120:        if(la <= lb)
                    121:        {
                    122:                while(a < aend)
                    123:                        if(*a != *b)
                    124:                                return( *a - *b );
                    125:                        else
                    126:                        {
                    127:                                ++a;
                    128:                                ++b;
                    129:                        }
                    130: 
                    131:                while(b < bend)
                    132:                        if(*b != ' ')
                    133:                                return(' ' - *b);
                    134:                        else
                    135:                                ++b;
                    136:        }
                    137: 
                    138:        else
                    139:        {
                    140:                while(b < bend)
                    141:                        if(*a != *b)
                    142:                                return( *a - *b );
                    143:                        else
                    144:                        {
                    145:                                ++a;
                    146:                                ++b;
                    147:                        }
                    148:                while(a < aend)
                    149:                        if(*a != ' ')
                    150:                                return(*a - ' ');
                    151:                        else
                    152:                                ++a;
                    153:        }
                    154:        return(0);
                    155: }
                    156: 
                    157: 
                    158: /* hookup -- Same as LISP NCONC, that is a destructive append of two lists */
                    159: 
                    160: chainp hookup(x,y)
                    161: register chainp x, y;
                    162: {
                    163:        register chainp p;
                    164: 
                    165:        if(x == NULL)
                    166:                return(y);
                    167: 
                    168:        for(p = x ; p->nextp ; p = p->nextp)
                    169:                ;
                    170:        p->nextp = y;
                    171:        return(x);
                    172: }
                    173: 
                    174: 
                    175: 
                    176: struct Listblock *mklist(p)
                    177: chainp p;
                    178: {
                    179:        register struct Listblock *q;
                    180: 
                    181:        q = ALLOC(Listblock);
                    182:        q->tag = TLIST;
                    183:        q->listp = p;
                    184:        return(q);
                    185: }
                    186: 
                    187: 
                    188: chainp mkchain(p,q)
                    189: register char * p;
                    190: register chainp q;
                    191: {
                    192:        register chainp r;
                    193: 
                    194:        if(chains)
                    195:        {
                    196:                r = chains;
                    197:                chains = chains->nextp;
                    198:        }
                    199:        else
                    200:                r = ALLOC(Chain);
                    201: 
                    202:        r->datap = p;
                    203:        r->nextp = q;
                    204:        return(r);
                    205: }
                    206: 
                    207:  chainp
                    208: revchain(next)
                    209:  register chainp next;
                    210: {
                    211:        register chainp p, prev = 0;
                    212: 
                    213:        while(p = next) {
                    214:                next = p->nextp;
                    215:                p->nextp = prev;
                    216:                prev = p;
                    217:                }
                    218:        return prev;
                    219:        }
                    220: 
                    221: 
                    222: /* addunder -- turn a cvarname into an external name */
                    223: /* The cvarname may already end in _ (to avoid C keywords); */
                    224: /* if not, it has room for appending an _. */
                    225: 
                    226:  char *
                    227: addunder(s)
                    228:  register char *s;
                    229: {
                    230:        register int c, i;
                    231:        char *s0 = s;
                    232: 
                    233:        i = 0;
                    234:        while(c = *s++)
                    235:                if (c == '_')
                    236:                        i++;
                    237:                else
                    238:                        i = 0;
                    239:        if (!i) {
                    240:                *s-- = 0;
                    241:                *s = '_';
                    242:                }
                    243:        return( s0 );
                    244:        }
                    245: 
                    246: 
                    247: /* copyn -- return a new copy of the input Fortran-string */
                    248: 
                    249: char *copyn(n, s)
                    250: register int n;
                    251: register char *s;
                    252: {
                    253:        register char *p, *q;
                    254: 
                    255:        p = q = (char *) Alloc(n);
                    256:        while(--n >= 0)
                    257:                *q++ = *s++;
                    258:        return(p);
                    259: }
                    260: 
                    261: 
                    262: 
                    263: /* copys -- return a new copy of the input C-string */
                    264: 
                    265: char *copys(s)
                    266: char *s;
                    267: {
                    268:        return( copyn( strlen(s)+1 , s) );
                    269: }
                    270: 
                    271: 
                    272: 
                    273: /* convci -- Convert Fortran-string to integer; assumes that input is a
                    274:    legal number, with no trailing blanks */
                    275: 
                    276: ftnint convci(n, s)
                    277: register int n;
                    278: register char *s;
                    279: {
                    280:        ftnint sum;
                    281:        sum = 0;
                    282:        while(n-- > 0)
                    283:                sum = 10*sum + (*s++ - '0');
                    284:        return(sum);
                    285: }
                    286: 
                    287: /* convic - Convert Integer constant to string */
                    288: 
                    289: char *convic(n)
                    290: ftnint n;
                    291: {
                    292:        static char s[20];
                    293:        register char *t;
                    294: 
                    295:        s[19] = '\0';
                    296:        t = s+19;
                    297: 
                    298:        do      {
                    299:                *--t = '0' + n%10;
                    300:                n /= 10;
                    301:        } while(n > 0);
                    302: 
                    303:        return(t);
                    304: }
                    305: 
                    306: 
                    307: 
                    308: /* mkname -- add a new identifier to the environment, including the closed
                    309:    hash table. */
                    310: 
                    311: Namep mkname(s)
                    312: register char *s;
                    313: {
                    314:        struct Hashentry *hp;
                    315:        register Namep q;
                    316:        register int c, hash, i;
                    317:        register char *t;
                    318:        char *s0;
                    319:        char errbuf[64];
                    320: 
                    321:        hash = i = 0;
                    322:        s0 = s;
                    323:        while(c = *s++) {
                    324:                hash += c;
                    325:                if (c == '_')
                    326:                        i = 2;
                    327:                }
                    328:        if (!i && in_vector(s0,c_keywords,n_keywords) >= 0)
                    329:                i = 1;
                    330:        hash %= maxhash;
                    331: 
                    332: /* Add the name to the closed hash table */
                    333: 
                    334:        hp = hashtab + hash;
                    335: 
                    336:        while(q = hp->varp)
                    337:                if( hash == hp->hashval && !strcmp(s0,q->fvarname) )
                    338:                        return(q);
                    339:                else if(++hp >= lasthash)
                    340:                        hp = hashtab;
                    341: 
                    342:        if(++nintnames >= maxhash-1)
                    343:                many("names", 'n', maxhash);    /* Fatal error */
                    344:        hp->varp = q = ALLOC(Nameblock);
                    345:        hp->hashval = hash;
                    346:        q->tag = TNAME; /* TNAME means the tag type is NAME */
                    347:        c = s - s0;
                    348:        if (c > 7 && noextflag) {
                    349:                sprintf(errbuf, "\"%.35s%s\" over 6 characters long", s0,
                    350:                        c > 36 ? "..." : "");
                    351:                errext(errbuf);
                    352:                }
                    353:        q->fvarname = strcpy(mem(c,0), s0);
                    354:        t = q->cvarname = mem(c + i + 1, 0);
                    355:        s = s0;
                    356:        /* add __ to the end of any name containing _ and to any C keyword */
                    357:        while(*t = *s++)
                    358:                t++;
                    359:        if (i) {
                    360:                do *t++ = '_';
                    361:                        while(--i > 0);
                    362:                *t = 0;
                    363:                }
                    364:        return(q);
                    365: }
                    366: 
                    367: 
                    368: struct Labelblock *mklabel(l)
                    369: ftnint l;
                    370: {
                    371:        register struct Labelblock *lp;
                    372: 
                    373:        if(l <= 0)
                    374:                return(NULL);
                    375: 
                    376:        for(lp = labeltab ; lp < highlabtab ; ++lp)
                    377:                if(lp->stateno == l)
                    378:                        return(lp);
                    379: 
                    380:        if(++highlabtab > labtabend)
                    381:                many("statement labels", 's', maxstno);
                    382: 
                    383:        lp->stateno = l;
                    384:        lp->labelno = newlabel();
                    385:        lp->blklevel = 0;
                    386:        lp->labused = NO;
                    387:        lp->fmtlabused = NO;
                    388:        lp->labdefined = NO;
                    389:        lp->labinacc = NO;
                    390:        lp->labtype = LABUNKNOWN;
                    391:        lp->fmtstring = 0;
                    392:        return(lp);
                    393: }
                    394: 
                    395: 
                    396: newlabel()
                    397: {
                    398:        return( ++lastlabno );
                    399: }
                    400: 
                    401: 
                    402: /* this label appears in a branch context */
                    403: 
                    404: struct Labelblock *execlab(stateno)
                    405: ftnint stateno;
                    406: {
                    407:        register struct Labelblock *lp;
                    408: 
                    409:        if(lp = mklabel(stateno))
                    410:        {
                    411:                if(lp->labinacc)
                    412:                        warn1("illegal branch to inner block, statement label %s",
                    413:                            convic(stateno) );
                    414:                else if(lp->labdefined == NO)
                    415:                        lp->blklevel = blklevel;
                    416:                if(lp->labtype == LABFORMAT)
                    417:                        err("may not branch to a format");
                    418:                else
                    419:                        lp->labtype = LABEXEC;
                    420:        }
                    421:        else
                    422:                execerr("illegal label %s", convic(stateno));
                    423: 
                    424:        return(lp);
                    425: }
                    426: 
                    427: 
                    428: /* find or put a name in the external symbol table */
                    429: 
                    430: Extsym *mkext(f,s)
                    431: char *f, *s;
                    432: {
                    433:        Extsym *p;
                    434: 
                    435:        for(p = extsymtab ; p<nextext ; ++p)
                    436:                if(!strcmp(s,p->cextname))
                    437:                        return( p );
                    438: 
                    439:        if(nextext >= lastext)
                    440:                many("external symbols", 'x', maxext);
                    441: 
                    442:        nextext->fextname = strcpy(gmem(strlen(f)+1,0), f);
                    443:        nextext->cextname = f == s
                    444:                                ? nextext->fextname
                    445:                                : strcpy(gmem(strlen(s)+1,0), s);
                    446:        nextext->extstg = STGUNKNOWN;
                    447:        nextext->extp = 0;
                    448:        nextext->allextp = 0;
                    449:        nextext->extleng = 0;
                    450:        nextext->maxleng = 0;
                    451:        nextext->extinit = 0;
                    452:        nextext->curno = nextext->maxno = 0;
                    453:        return( nextext++ );
                    454: }
                    455: 
                    456: 
                    457: Addrp builtin(t, s, dbi)
                    458: int t, dbi;
                    459: char *s;
                    460: {
                    461:        register Extsym *p;
                    462:        register Addrp q;
                    463:        extern chainp used_builtins;
                    464: 
                    465:        p = mkext(s,s);
                    466:        if(p->extstg == STGUNKNOWN)
                    467:                p->extstg = STGEXT;
                    468:        else if(p->extstg != STGEXT)
                    469:        {
                    470:                errstr("improper use of builtin %s", s);
                    471:                return(0);
                    472:        }
                    473: 
                    474:        q = ALLOC(Addrblock);
                    475:        q->tag = TADDR;
                    476:        q->vtype = t;
                    477:        q->vclass = CLPROC;
                    478:        q->vstg = STGEXT;
                    479:        q->memno = p - extsymtab;
                    480:        q->dbl_builtin = dbi;
                    481: 
                    482: /* A NULL pointer here tells you to use   memno   to check the external
                    483:    symbol table */
                    484: 
                    485:        q -> uname_tag = UNAM_EXTERN;
                    486: 
                    487: /* Add to the list of used builtins */
                    488: 
                    489:        if (dbi >= 0)
                    490:                add_extern_to_list (q, &used_builtins);
                    491:        return(q);
                    492: }
                    493: 
                    494: 
                    495: 
                    496: add_extern_to_list (addr, list_store)
                    497: Addrp addr;
                    498: chainp *list_store;
                    499: {
                    500:     chainp last = CHNULL;
                    501:     chainp list;
                    502:     int memno;
                    503: 
                    504:     if (list_store == (chainp *) NULL || addr == (Addrp) NULL)
                    505:        return;
                    506: 
                    507:     list = *list_store;
                    508:     memno = addr -> memno;
                    509: 
                    510:     for (;list; last = list, list = list -> nextp) {
                    511:        Addrp this = (Addrp) (list -> datap);
                    512: 
                    513:        if (this -> tag == TADDR && this -> uname_tag == UNAM_EXTERN &&
                    514:                this -> memno == memno)
                    515:            return;
                    516:     } /* for */
                    517: 
                    518:     if (*list_store == CHNULL)
                    519:        *list_store = mkchain((char *)cpexpr((expptr)addr), CHNULL);
                    520:     else
                    521:        last->nextp = mkchain((char *)cpexpr((expptr)addr), CHNULL);
                    522: 
                    523: } /* add_extern_to_list */
                    524: 
                    525: 
                    526: frchain(p)
                    527: register chainp *p;
                    528: {
                    529:        register chainp q;
                    530: 
                    531:        if(p==0 || *p==0)
                    532:                return;
                    533: 
                    534:        for(q = *p; q->nextp ; q = q->nextp)
                    535:                ;
                    536:        q->nextp = chains;
                    537:        chains = *p;
                    538:        *p = 0;
                    539: }
                    540: 
                    541:  void
                    542: frexchain(p)
                    543:  register chainp *p;
                    544: {
                    545:        register chainp q, r;
                    546: 
                    547:        if (q = *p) {
                    548:                for(;;q = r) {
                    549:                        frexpr((expptr)q->datap);
                    550:                        if (!(r = q->nextp))
                    551:                                break;
                    552:                        }
                    553:                q->nextp = chains;
                    554:                chains = *p;
                    555:                *p = 0;
                    556:                }
                    557:        }
                    558: 
                    559: 
                    560: tagptr cpblock(n,p)
                    561: register int n;
                    562: register char * p;
                    563: {
                    564:        register ptr q;
                    565: 
                    566:        memcpy((char *)(q = ckalloc(n)), (char *)p, n);
                    567:        return( (tagptr) q);
                    568: }
                    569: 
                    570: 
                    571: 
                    572: ftnint lmax(a, b)
                    573: ftnint a, b;
                    574: {
                    575:        return( a>b ? a : b);
                    576: }
                    577: 
                    578: ftnint lmin(a, b)
                    579: ftnint a, b;
                    580: {
                    581:        return(a < b ? a : b);
                    582: }
                    583: 
                    584: 
                    585: 
                    586: 
                    587: maxtype(t1, t2)
                    588: int t1, t2;
                    589: {
                    590:        int t;
                    591: 
                    592:        t = t1 >= t2 ? t1 : t2;
                    593:        if(t==TYCOMPLEX && (t1==TYDREAL || t2==TYDREAL) )
                    594:                t = TYDCOMPLEX;
                    595:        return(t);
                    596: }
                    597: 
                    598: 
                    599: 
                    600: /* return log base 2 of n if n a power of 2; otherwise -1 */
                    601: log_2(n)
                    602: ftnint n;
                    603: {
                    604:        int k;
                    605: 
                    606:        /* trick based on binary representation */
                    607: 
                    608:        if(n<=0 || (n & (n-1))!=0)
                    609:                return(-1);
                    610: 
                    611:        for(k = 0 ;  n >>= 1  ; ++k)
                    612:                ;
                    613:        return(k);
                    614: }
                    615: 
                    616: 
                    617: 
                    618: frrpl()
                    619: {
                    620:        struct Rplblock *rp;
                    621: 
                    622:        while(rpllist)
                    623:        {
                    624:                rp = rpllist->rplnextp;
                    625:                free( (charptr) rpllist);
                    626:                rpllist = rp;
                    627:        }
                    628: }
                    629: 
                    630: 
                    631: 
                    632: /* Call a Fortran function with an arbitrary list of arguments */
                    633: 
                    634: int callk_kludge;
                    635: 
                    636: expptr callk(type, name, args)
                    637: int type;
                    638: char *name;
                    639: chainp args;
                    640: {
                    641:        register expptr p;
                    642: 
                    643:        p = mkexpr(OPCALL,
                    644:                (expptr)builtin(callk_kludge ? callk_kludge : type, name, 0),
                    645:                (expptr)args);
                    646:        p->exprblock.vtype = type;
                    647:        return(p);
                    648: }
                    649: 
                    650: 
                    651: 
                    652: expptr call4(type, name, arg1, arg2, arg3, arg4)
                    653: int type;
                    654: char *name;
                    655: expptr arg1, arg2, arg3, arg4;
                    656: {
                    657:        struct Listblock *args;
                    658:        args = mklist( mkchain((char *)arg1,
                    659:                        mkchain((char *)arg2,
                    660:                                mkchain((char *)arg3,
                    661:                                        mkchain((char *)arg4, CHNULL)) ) ) );
                    662:        return( callk(type, name, (chainp)args) );
                    663: }
                    664: 
                    665: 
                    666: 
                    667: 
                    668: expptr call3(type, name, arg1, arg2, arg3)
                    669: int type;
                    670: char *name;
                    671: expptr arg1, arg2, arg3;
                    672: {
                    673:        struct Listblock *args;
                    674:        args = mklist( mkchain((char *)arg1,
                    675:                        mkchain((char *)arg2,
                    676:                                mkchain((char *)arg3, CHNULL) ) ) );
                    677:        return( callk(type, name, (chainp)args) );
                    678: }
                    679: 
                    680: 
                    681: 
                    682: 
                    683: 
                    684: expptr call2(type, name, arg1, arg2)
                    685: int type;
                    686: char *name;
                    687: expptr arg1, arg2;
                    688: {
                    689:        struct Listblock *args;
                    690: 
                    691:        args = mklist( mkchain((char *)arg1, mkchain((char *)arg2, CHNULL) ) );
                    692:        return( callk(type,name, (chainp)args) );
                    693: }
                    694: 
                    695: 
                    696: 
                    697: 
                    698: expptr call1(type, name, arg)
                    699: int type;
                    700: char *name;
                    701: expptr arg;
                    702: {
                    703:        return( callk(type,name, (chainp)mklist(mkchain((char *)arg,CHNULL)) ));
                    704: }
                    705: 
                    706: 
                    707: expptr call0(type, name)
                    708: int type;
                    709: char *name;
                    710: {
                    711:        return( callk(type, name, CHNULL) );
                    712: }
                    713: 
                    714: 
                    715: 
                    716: struct Impldoblock *mkiodo(dospec, list)
                    717: chainp dospec, list;
                    718: {
                    719:        register struct Impldoblock *q;
                    720: 
                    721:        q = ALLOC(Impldoblock);
                    722:        q->tag = TIMPLDO;
                    723:        q->impdospec = dospec;
                    724:        q->datalist = list;
                    725:        return(q);
                    726: }
                    727: 
                    728: 
                    729: 
                    730: 
                    731: /* ckalloc -- Allocate 1 memory unit of size   n,   checking for out of
                    732:    memory error */
                    733: 
                    734: ptr ckalloc(n)
                    735: register int n;
                    736: {
                    737:        register ptr p;
                    738:        p = (ptr)calloc(1, (unsigned) n);
                    739:        if (p || !n)
                    740:                return(p);
                    741:        fprintf(stderr, "failing to get %d bytes\n",n);
                    742:        Fatal("out of memory");
                    743:        /* NOT REACHED */ return 0;
                    744: }
                    745: 
                    746: 
                    747: 
                    748: isaddr(p)
                    749: register expptr p;
                    750: {
                    751:        if(p->tag == TADDR)
                    752:                return(YES);
                    753:        if(p->tag == TEXPR)
                    754:                switch(p->exprblock.opcode)
                    755:                {
                    756:                case OPCOMMA:
                    757:                        return( isaddr(p->exprblock.rightp) );
                    758: 
                    759:                case OPASSIGN:
                    760:                case OPASSIGNI:
                    761:                case OPPLUSEQ:
                    762:                case OPMINUSEQ:
                    763:                case OPSLASHEQ:
                    764:                case OPMODEQ:
                    765:                case OPLSHIFTEQ:
                    766:                case OPRSHIFTEQ:
                    767:                case OPBITANDEQ:
                    768:                case OPBITXOREQ:
                    769:                case OPBITOREQ:
                    770:                        return( isaddr(p->exprblock.leftp) );
                    771:                }
                    772:        return(NO);
                    773: }
                    774: 
                    775: 
                    776: 
                    777: 
                    778: isstatic(p)
                    779: register expptr p;
                    780: {
                    781:        extern int useauto;
                    782:        if(p->headblock.vleng && !ISCONST(p->headblock.vleng))
                    783:                return(NO);
                    784: 
                    785:        switch(p->tag)
                    786:        {
                    787:        case TCONST:
                    788:                return(YES);
                    789: 
                    790:        case TADDR:
                    791:                if(ONEOF(p->addrblock.vstg,MSKSTATIC) &&
                    792:                    ISCONST(p->addrblock.memoffset) && !useauto)
                    793:                        return(YES);
                    794: 
                    795:        default:
                    796:                return(NO);
                    797:        }
                    798: }
                    799: 
                    800: 
                    801: 
                    802: /* addressable -- return True iff it is a constant value, or can be
                    803:    referenced by constant values */
                    804: 
                    805: addressable(p)
                    806: register expptr p;
                    807: {
                    808:        switch(p->tag)
                    809:        {
                    810:        case TCONST:
                    811:                return(YES);
                    812: 
                    813:        case TADDR:
                    814:                return( addressable(p->addrblock.memoffset) );
                    815: 
                    816:        default:
                    817:                return(NO);
                    818:        }
                    819: }
                    820: 
                    821: 
                    822: /* isnegative_const -- returns true if the constant is negative.  Returns
                    823:    false for imaginary and nonnumeric constants */
                    824: 
                    825: int isnegative_const (cp)
                    826: struct Constblock *cp;
                    827: {
                    828:     int retval;
                    829: 
                    830:     if (cp == NULL)
                    831:        return 0;
                    832: 
                    833:     switch (cp -> vtype) {
                    834:        case TYINT1:
                    835:         case TYSHORT:
                    836:        case TYLONG:
                    837: #ifdef TYQUAD
                    838:        case TYQUAD:
                    839: #endif
                    840:            retval = cp -> Const.ci < 0;
                    841:            break;
                    842:        case TYREAL:
                    843:        case TYDREAL:
                    844:                retval = cp->vstg ? *cp->Const.cds[0] == '-'
                    845:                                  :  cp->Const.cd[0] < 0.0;
                    846:            break;
                    847:        default:
                    848: 
                    849:            retval = 0;
                    850:            break;
                    851:     } /* switch */
                    852: 
                    853:     return retval;
                    854: } /* isnegative_const */
                    855: 
                    856: negate_const(cp)
                    857:  Constp cp;
                    858: {
                    859:     if (cp == (struct Constblock *) NULL)
                    860:        return;
                    861: 
                    862:     switch (cp -> vtype) {
                    863:        case TYINT1:
                    864:        case TYSHORT:
                    865:        case TYLONG:
                    866: #ifdef TYQUAD
                    867:        case TYQUAD:
                    868: #endif
                    869:            cp -> Const.ci = - cp -> Const.ci;
                    870:            break;
                    871:        case TYCOMPLEX:
                    872:        case TYDCOMPLEX:
                    873:                if (cp->vstg)
                    874:                    switch(*cp->Const.cds[1]) {
                    875:                        case '-':
                    876:                                ++cp->Const.cds[1];
                    877:                                break;
                    878:                        case '0':
                    879:                                break;
                    880:                        default:
                    881:                                --cp->Const.cds[1];
                    882:                        }
                    883:                else
                    884:                        cp->Const.cd[1] = -cp->Const.cd[1];
                    885:                /* no break */
                    886:        case TYREAL:
                    887:        case TYDREAL:
                    888:                if (cp->vstg)
                    889:                    switch(*cp->Const.cds[0]) {
                    890:                        case '-':
                    891:                                ++cp->Const.cds[0];
                    892:                                break;
                    893:                        case '0':
                    894:                                break;
                    895:                        default:
                    896:                                --cp->Const.cds[0];
                    897:                        }
                    898:                else
                    899:                        cp->Const.cd[0] = -cp->Const.cd[0];
                    900:            break;
                    901:        case TYCHAR:
                    902:        case TYLOGICAL1:
                    903:        case TYLOGICAL2:
                    904:        case TYLOGICAL:
                    905:            erri ("negate_const:  can't negate type '%d'", cp -> vtype);
                    906:            break;
                    907:        default:
                    908:            erri ("negate_const:  bad type '%d'",
                    909:                    cp -> vtype);
                    910:            break;
                    911:     } /* switch */
                    912: } /* negate_const */
                    913: 
                    914: ffilecopy (infp, outfp)
                    915: FILE *infp, *outfp;
                    916: {
                    917:     while (!feof (infp)) {
                    918:        register c = getc (infp);
                    919:        if (!feof (infp))
                    920:        putc (c, outfp);
                    921:     } /* while */
                    922: } /* ffilecopy */
                    923: 
                    924: 
                    925: /* in_vector -- verifies whether   str   is in c_keywords.
                    926:    If so, the index is returned else  -1  is returned.
                    927:    c_keywords must be in alphabetical order (as defined by strcmp).
                    928: */
                    929: 
                    930: int in_vector(str, keywds, n)
                    931: char *str; char **keywds; register int n;
                    932: {
                    933:        register char **K = keywds;
                    934:        register int n1, t;
                    935: 
                    936:        do {
                    937:                n1 = n >> 1;
                    938:                if (!(t = strcmp(str, K[n1])))
                    939:                        return K - keywds + n1;
                    940:                if (t < 0)
                    941:                        n = n1;
                    942:                else {
                    943:                        n -= ++n1;
                    944:                        K += n1;
                    945:                        }
                    946:                }
                    947:                while(n > 0);
                    948: 
                    949:        return -1;
                    950:        } /* in_vector */
                    951: 
                    952: 
                    953: int is_negatable (Const)
                    954: Constp Const;
                    955: {
                    956:     int retval = 0;
                    957:     if (Const != (Constp) NULL)
                    958:        switch (Const -> vtype) {
                    959:            case TYINT1:
                    960:                retval = Const -> Const.ci >= -BIGGEST_CHAR;
                    961:                break;
                    962:            case TYSHORT:
                    963:                retval = Const -> Const.ci >= -BIGGEST_SHORT;
                    964:                break;
                    965:            case TYLONG:
                    966: #ifdef TYQUAD
                    967:            case TYQUAD:
                    968: #endif
                    969:                retval = Const -> Const.ci >= -BIGGEST_LONG;
                    970:                break;
                    971:            case TYREAL:
                    972:            case TYDREAL:
                    973:            case TYCOMPLEX:
                    974:            case TYDCOMPLEX:
                    975:                retval = 1;
                    976:                break;
                    977:            case TYLOGICAL1:
                    978:            case TYLOGICAL2:
                    979:            case TYLOGICAL:
                    980:            case TYCHAR:
                    981:            case TYSUBR:
                    982:            default:
                    983:                retval = 0;
                    984:                break;
                    985:        } /* switch */
                    986: 
                    987:     return retval;
                    988: } /* is_negatable */
                    989: 
                    990: backup(fname, bname)
                    991:  char *fname, *bname;
                    992: {
                    993:        FILE *b, *f;
                    994:        static char couldnt[] = "Couldn't open %.80s";
                    995: 
                    996:        if (!(f = fopen(fname, binread))) {
                    997:                warn1(couldnt, fname);
                    998:                return;
                    999:                }
                   1000:        if (!(b = fopen(bname, binwrite))) {
                   1001:                warn1(couldnt, bname);
                   1002:                return;
                   1003:                }
                   1004:        ffilecopy(f, b);
                   1005:        fclose(f);
                   1006:        fclose(b);
                   1007:        }
                   1008: 
                   1009: 
                   1010: /* struct_eq -- returns YES if structures have the same field names and
                   1011:    types, NO otherwise */
                   1012: 
                   1013: int struct_eq (s1, s2)
                   1014: chainp s1, s2;
                   1015: {
                   1016:     struct Dimblock *d1, *d2;
                   1017:     Constp cp1, cp2;
                   1018: 
                   1019:     if (s1 == CHNULL && s2 == CHNULL)
                   1020:        return YES;
                   1021:     for(; s1 && s2; s1 = s1->nextp, s2 = s2->nextp) {
                   1022:        register Namep v1 = (Namep) s1 -> datap;
                   1023:        register Namep v2 = (Namep) s2 -> datap;
                   1024: 
                   1025:        if (v1 == (Namep) NULL || v1 -> tag != TNAME ||
                   1026:                v2 == (Namep) NULL || v2 -> tag != TNAME)
                   1027:            return NO;
                   1028: 
                   1029:        if (v1->vtype != v2->vtype || v1->vclass != v2->vclass
                   1030:                || strcmp(v1->fvarname, v2->fvarname))
                   1031:            return NO;
                   1032: 
                   1033:        /* compare dimensions (needed for comparing COMMON blocks) */
                   1034: 
                   1035:        if (d1 = v1->vdim) {
                   1036:                if (!(cp1 = (Constp)d1->nelt) || cp1->tag != TCONST)
                   1037:                        return NO;
                   1038:                if (!(d2 = v2->vdim))
                   1039:                        if (cp1->Const.ci == 1)
                   1040:                                continue;
                   1041:                        else
                   1042:                                return NO;
                   1043:                if (!(cp2 = (Constp)d2->nelt) || cp2->tag != TCONST
                   1044:                ||  cp1->Const.ci != cp2->Const.ci)
                   1045:                        return NO;
                   1046:                }
                   1047:        else if ((d2 = v2->vdim) && (!(cp2 = (Constp)d2->nelt)
                   1048:                                || cp2->tag != TCONST
                   1049:                                || cp2->Const.ci != 1))
                   1050:                return NO;
                   1051:     } /* while s1 != CHNULL && s2 != CHNULL */
                   1052: 
                   1053:     return s1 == CHNULL && s2 == CHNULL;
                   1054: } /* struct_eq */

unix.superglobalmegacorp.com

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