home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 8
/
FreshFishVol8-CD2.bin
/
bbs
/
gnu
/
f2c-1993.04.28-src.lha
/
f2c-1993.04.28
/
src
/
misc.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-28
|
18KB
|
1,055 lines
/****************************************************************
Copyright 1990, 1992, 1993 by AT&T Bell Laboratories and Bellcore.
Permission to use, copy, modify, and distribute this software
and its documentation for any purpose and without fee is hereby
granted, provided that the above copyright notice appear in all
copies and that both that the copyright notice and this
permission notice and warranty disclaimer appear in supporting
documentation, and that the names of AT&T Bell Laboratories or
Bellcore or any of their entities not be used in advertising or
publicity pertaining to distribution of the software without
specific, written prior permission.
AT&T and Bellcore disclaim all warranties with regard to this
software, including all implied warranties of merchantability
and fitness. In no event shall AT&T or Bellcore be liable for
any special, indirect or consequential damages or any damages
whatsoever resulting from loss of use, data or profits, whether
in an action of contract, negligence or other tortious action,
arising out of or in connection with the use or performance of
this software.
****************************************************************/
#include "defs.h"
int oneof_stg (name, stg, mask)
Namep name;
int stg, mask;
{
if (stg == STGCOMMON && name) {
if ((mask & M(STGEQUIV)))
return name->vcommequiv;
if ((mask & M(STGCOMMON)))
return !name->vcommequiv;
}
return ONEOF(stg, mask);
}
/* op_assign -- given a binary opcode, return the associated assignment
operator */
int op_assign (opcode)
int opcode;
{
int retval = -1;
switch (opcode) {
case OPPLUS: retval = OPPLUSEQ; break;
case OPMINUS: retval = OPMINUSEQ; break;
case OPSTAR: retval = OPSTAREQ; break;
case OPSLASH: retval = OPSLASHEQ; break;
case OPMOD: retval = OPMODEQ; break;
case OPLSHIFT: retval = OPLSHIFTEQ; break;
case OPRSHIFT: retval = OPRSHIFTEQ; break;
case OPBITAND: retval = OPBITANDEQ; break;
case OPBITXOR: retval = OPBITXOREQ; break;
case OPBITOR: retval = OPBITOREQ; break;
default:
erri ("op_assign: bad opcode '%d'", opcode);
break;
} /* switch */
return retval;
} /* op_assign */
char *
Alloc(n) /* error-checking version of malloc */
/* ckalloc initializes memory to 0; Alloc does not */
int n;
{
char errbuf[32];
register char *rv;
rv = malloc(n);
if (!rv) {
sprintf(errbuf, "malloc(%d) failure!", n);
Fatal(errbuf);
}
return rv;
}
cpn(n, a, b)
register int n;
register char *a, *b;
{
while(--n >= 0)
*b++ = *a++;
}
eqn(n, a, b)
register int n;
register char *a, *b;
{
while(--n >= 0)
if(*a++ != *b++)
return(NO);
return(YES);
}
cmpstr(a, b, la, lb) /* compare two strings */
register char *a, *b;
ftnint la, lb;
{
register char *aend, *bend;
aend = a + la;
bend = b + lb;
if(la <= lb)
{
while(a < aend)
if(*a != *b)
return( *a - *b );
else
{
++a;
++b;
}
while(b < bend)
if(*b != ' ')
return(' ' - *b);
else
++b;
}
else
{
while(b < bend)
if(*a != *b)
return( *a - *b );
else
{
++a;
++b;
}
while(a < aend)
if(*a != ' ')
return(*a - ' ');
else
++a;
}
return(0);
}
/* hookup -- Same as LISP NCONC, that is a destructive append of two lists */
chainp hookup(x,y)
register chainp x, y;
{
register chainp p;
if(x == NULL)
return(y);
for(p = x ; p->nextp ; p = p->nextp)
;
p->nextp = y;
return(x);
}
struct Listblock *mklist(p)
chainp p;
{
register struct Listblock *q;
q = ALLOC(Listblock);
q->tag = TLIST;
q->listp = p;
return(q);
}
chainp mkchain(p,q)
register char * p;
register chainp q;
{
register chainp r;
if(chains)
{
r = chains;
chains = chains->nextp;
}
else
r = ALLOC(Chain);
r->datap = p;
r->nextp = q;
return(r);
}
chainp
revchain(next)
register chainp next;
{
register chainp p, prev = 0;
while(p = next) {
next = p->nextp;
p->nextp = prev;
prev = p;
}
return prev;
}
/* addunder -- turn a cvarname into an external name */
/* The cvarname may already end in _ (to avoid C keywords); */
/* if not, it has room for appending an _. */
char *
addunder(s)
register char *s;
{
register int c, i;
char *s0 = s;
i = 0;
while(c = *s++)
if (c == '_')
i++;
else
i = 0;
if (!i) {
*s-- = 0;
*s = '_';
}
return( s0 );
}
/* copyn -- return a new copy of the input Fortran-string */
char *copyn(n, s)
register int n;
register char *s;
{
register char *p, *q;
p = q = (char *) Alloc(n);
while(--n >= 0)
*q++ = *s++;
return(p);
}
/* copys -- return a new copy of the input C-string */
char *copys(s)
char *s;
{
return( copyn( strlen(s)+1 , s) );
}
/* convci -- Convert Fortran-string to integer; assumes that input is a
legal number, with no trailing blanks */
ftnint convci(n, s)
register int n;
register char *s;
{
ftnint sum;
sum = 0;
while(n-- > 0)
sum = 10*sum + (*s++ - '0');
return(sum);
}
/* convic - Convert Integer constant to string */
char *convic(n)
ftnint n;
{
static char s[20];
register char *t;
s[19] = '\0';
t = s+19;
do {
*--t = '0' + n%10;
n /= 10;
} while(n > 0);
return(t);
}
/* mkname -- add a new identifier to the environment, including the closed
hash table. */
Namep mkname(s)
register char *s;
{
struct Hashentry *hp;
register Namep q;
register int c, hash, i;
register char *t;
char *s0;
char errbuf[64];
hash = i = 0;
s0 = s;
while(c = *s++) {
hash += c;
if (c == '_')
i = 2;
}
if (!i && in_vector(s0,c_keywords,n_keywords) >= 0)
i = 1;
hash %= maxhash;
/* Add the name to the closed hash table */
hp = hashtab + hash;
while(q = hp->varp)
if( hash == hp->hashval && !strcmp(s0,q->fvarname) )
return(q);
else if(++hp >= lasthash)
hp = hashtab;
if(++nintnames >= maxhash-1)
many("names", 'n', maxhash); /* Fatal error */
hp->varp = q = ALLOC(Nameblock);
hp->hashval = hash;
q->tag = TNAME; /* TNAME means the tag type is NAME */
c = s - s0;
if (c > 7 && noextflag) {
sprintf(errbuf, "\"%.35s%s\" over 6 characters long", s0,
c > 36 ? "..." : "");
errext(errbuf);
}
q->fvarname = strcpy(mem(c,0), s0);
t = q->cvarname = mem(c + i + 1, 0);
s = s0;
/* add __ to the end of any name containing _ and to any C keyword */
while(*t = *s++)
t++;
if (i) {
do *t++ = '_';
while(--i > 0);
*t = 0;
}
return(q);
}
struct Labelblock *mklabel(l)
ftnint l;
{
register struct Labelblock *lp;
if(l <= 0)
return(NULL);
for(lp = labeltab ; lp < highlabtab ; ++lp)
if(lp->stateno == l)
return(lp);
if(++highlabtab > labtabend)
many("statement labels", 's', maxstno);
lp->stateno = l;
lp->labelno = newlabel();
lp->blklevel = 0;
lp->labused = NO;
lp->fmtlabused = NO;
lp->labdefined = NO;
lp->labinacc = NO;
lp->labtype = LABUNKNOWN;
lp->fmtstring = 0;
return(lp);
}
newlabel()
{
return( ++lastlabno );
}
/* this label appears in a branch context */
struct Labelblock *execlab(stateno)
ftnint stateno;
{
register struct Labelblock *lp;
if(lp = mklabel(stateno))
{
if(lp->labinacc)
warn1("illegal branch to inner block, statement label %s",
convic(stateno) );
else if(lp->labdefined == NO)
lp->blklevel = blklevel;
if(lp->labtype == LABFORMAT)
err("may not branch to a format");
else
lp->labtype = LABEXEC;
}
else
execerr("illegal label %s", convic(stateno));
return(lp);
}
/* find or put a name in the external symbol table */
Extsym *mkext(f,s)
char *f, *s;
{
Extsym *p;
for(p = extsymtab ; p<nextext ; ++p)
if(!strcmp(s,p->cextname))
return( p );
if(nextext >= lastext)
many("external symbols", 'x', maxext);
nextext->fextname = strcpy(gmem(strlen(f)+1,0), f);
nextext->cextname = f == s
? nextext->fextname
: strcpy(gmem(strlen(s)+1,0), s);
nextext->extstg = STGUNKNOWN;
nextext->extp = 0;
nextext->allextp = 0;
nextext->extleng = 0;
nextext->maxleng = 0;
nextext->extinit = 0;
nextext->curno = nextext->maxno = 0;
return( nextext++ );
}
Addrp builtin(t, s, dbi)
int t, dbi;
char *s;
{
register Extsym *p;
register Addrp q;
extern chainp used_builtins;
p = mkext(s,s);
if(p->extstg == STGUNKNOWN)
p->extstg = STGEXT;
else if