equiv.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 370 行

C
370
字号
#ifndef lintstatic char	*sccsid = " @(#)equiv.c	1.3	(ULTRIX)	1/15/86";#endif lint/************************************************************************ *									* *			Copyright (c) 1986 by				* *		Digital Equipment Corporation, Maynard, MA		* *			All rights reserved.				* *									* *   This software is furnished under a license and may be used and	* *   copied  only  in accordance with the terms of such license and	* *   with the  inclusion  of  the  above  copyright  notice.   This	* *   software  or  any  other copies thereof may not be provided or	* *   otherwise made available to any other person.  No title to and	* *   ownership of the software is hereby transferred.			* *									* *   This software is  derived  from  software  received  from  the	* *   University    of   California,   Berkeley,   and   from   Bell	* *   Laboratories.  Use, duplication, or disclosure is  subject  to	* *   restrictions  under  license  agreements  with  University  of	* *   California and with AT&T.						* *									* *   The information in this software is subject to change  without	* *   notice  and should not be construed as a commitment by Digital	* *   Equipment Corporation.						* *									* *   Digital assumes no responsibility for the use  or  reliability	* *   of its software on equipment which is not supplied by Digital.	* *									* ************************************************************************//**************************************************************************			Modification History**	David Metsky		14-Jan-86** 001	Replaced old version with BSD 4.3 version as part of upgrade.**	Based on:	equiv.c		5.1		6/7/85**************************************************************************//* * equiv.c * * Routines related to equivalence class processing, f77 compiler, 4.2 BSD. * * University of Utah CS Dept modification history: *  * Revision 3.2  85/01/14  00:14:12  donn * Fixed bug in eqvcommon that was causing the calculations of multilevel * equivalences to be screwed up. *  * Revision 3.1  84/10/13  01:16:08  donn * Installed Jerry Berkman's version; added UofU comment header. *  */#include "defs.h"#ifdef SDB#	include <a.out.h>#	ifndef N_SO#		include <stab.h>#	endif#endif/* called at end of declarations section to process chains   created by EQUIVALENCE statements */doequiv(){register int i;int inequiv, comno, ovarno;ftnint comoffset, offset, leng;register struct Equivblock *p;register struct Eqvchain *q;struct Primblock *itemp;register Namep np;expptr offp, suboffset();int ns, nsubs();chainp cp;char *memname();int doeqverr = 0;for(i = 0 ; i < nequiv ; ++i)	{	p = &eqvclass[i];	p->eqvbottom = p->eqvtop = 0;	comno = -1;	for(q = p->equivs ; q ; q = q->eqvnextp)		{		offset = 0;		itemp = q->eqvitem.eqvlhs;		if( itemp == NULL ) fatal("error processing equivalence");		equivdcl = YES;		vardcl(np = itemp->namep);		equivdcl = NO;		if(itemp->argsp || itemp->fcharp)			{			if(np->vdim!=NULL && np->vdim->ndim>1 &&			   nsubs(itemp->argsp)==1 )				{				if(! ftn66flag)					warn("1-dim subscript in EQUIVALENCE");				cp = NULL;				ns = np->vdim->ndim;				while(--ns > 0)					cp = mkchain( ICON(1), cp);				itemp->argsp->listp->nextp = cp;				}			offp = suboffset(itemp);			if(ISICON(offp))				offset = offp->constblock.const.ci;			else	{				dclerr("illegal subscript in equivalence ",					np);				np = NULL;				doeqverr = 1;				}			frexpr(offp);			}		frexpr(itemp);		if(np && (leng = iarrlen(np))<0)			{			dclerr("argument in equivalence", np);			np = NULL;			doeqverr =1;			}		if(np) switch(np->vstg)			{			case STGUNKNOWN:			case STGBSS:			case STGEQUIV:				break;			case STGCOMMON:				comno = np->vardesc.varno;				comoffset = np->voffset + offset;				break;			default:				dclerr("bad storage class in equivalence", np);				np = NULL;				doeqverr = 1;				break;			}		if(np)			{			q->eqvoffset = offset;			p->eqvbottom = lmin(p->eqvbottom, -offset);			p->eqvtop = lmax(p->eqvtop, leng-offset);			}		q->eqvitem.eqvname = np;		}	if(comno >= 0)		eqvcommon(p, comno, comoffset);	else  for(q = p->equivs ; q ; q = q->eqvnextp)		{		if(np = q->eqvitem.eqvname)			{			inequiv = NO;			if(np->vstg==STGEQUIV)				if( (ovarno = np->vardesc.varno) == i)					{					if(np->voffset + q->eqvoffset != 0)						dclerr("inconsistent equivalence", np);						doeqverr = 1;					}				else	{					offset = np->voffset;					inequiv = YES;					}			np->vstg = STGEQUIV;			np->vardesc.varno = i;			np->voffset = - q->eqvoffset;			if(inequiv)				eqveqv(i, ovarno, q->eqvoffset + offset);			}		}	}if( !doeqverr )  for(i = 0 ; i < nequiv ; ++i)	{	p = & eqvclass[i];	if(p->eqvbottom!=0 || p->eqvtop!=0)	/* a live chain */		{		for(q = p->equivs ; q; q = q->eqvnextp)			{			np = q->eqvitem.eqvname;			np->voffset -= p->eqvbottom;			if(np->voffset % typealign[np->vtype] != 0)				dclerr("bad alignment forced by equivalence", np);			}		p->eqvtop -= p->eqvbottom;		p->eqvbottom = 0; 		}	freqchain(p);	}}/* put equivalence chain p at common block comno + comoffset */LOCAL eqvcommon(p, comno, comoffset)struct Equivblock *p;int comno;ftnint comoffset;{int ovarno;ftnint k, offq;register Namep np;register struct Eqvchain *q;if(comoffset + p->eqvbottom < 0)	{	errstr("attempt to extend common %s backward",		nounder(XL, extsymtab[comno].extname) );	freqchain(p);	return;	}if( (k = comoffset + p->eqvtop) > extsymtab[comno].extleng)	extsymtab[comno].extleng = k;#ifdef SDBif(sdbflag)	prstab( varstr(XL,extsymtab[comno].extname), N_BCOMM,0,0);#endiffor(q = p->equivs ; q ; q = q->eqvnextp)	if(np = q->eqvitem.eqvname)		{		switch(np->vstg)			{			case STGUNKNOWN:			case STGBSS:				np->vstg = STGCOMMON;				np->vardesc.varno = comno;				np->voffset = comoffset - q->eqvoffset;#ifdef SDB				if(sdbflag)					{					namestab(np);					}#endif				break;			case STGEQUIV:				ovarno = np->vardesc.varno;				offq = comoffset - q->eqvoffset - np->voffset;				np->vstg = STGCOMMON;				np->vardesc.varno = comno;				np->voffset = comoffset + q->eqvoffset;				if(ovarno != (p - eqvclass))					eqvcommon(&eqvclass[ovarno], comno, offq);#ifdef SDB				if(sdbflag)					{					namestab(np);					}#endif				break;			case STGCOMMON:				if(comno != np->vardesc.varno ||				   comoffset != np->voffset+q->eqvoffset)					dclerr("inconsistent common usage", np);				break;			default:				badstg("eqvcommon", np->vstg);			}		}#ifdef SDBif(sdbflag)	prstab( varstr(XL,extsymtab[comno].extname), N_ECOMM,0,0);#endiffreqchain(p);p->eqvbottom = p->eqvtop = 0;}/* put all items on ovarno chain on front of nvarno chain * adjust offsets of ovarno elements and top and bottom of nvarno chain */LOCAL eqveqv(nvarno, ovarno, delta)int ovarno, nvarno;ftnint delta;{register struct Equivblock *p0, *p;register Namep np;struct Eqvchain *q, *q1;p0 = eqvclass + nvarno;p = eqvclass + ovarno;p0->eqvbottom = lmin(p0->eqvbottom, p->eqvbottom - delta);p0->eqvtop = lmax(p0->eqvtop, p->eqvtop - delta);p->eqvbottom = p->eqvtop = 0;for(q = p->equivs ; q ; q = q1)	{	q1 = q->eqvnextp;	if( (np = q->eqvitem.eqvname) && np->vardesc.varno==ovarno)		{		q->eqvnextp = p0->equivs;		p0->equivs = q;		q->eqvoffset -= delta;		np->vardesc.varno = nvarno;		np->voffset -= delta;		}	else	free( (charptr) q);	}p->equivs = NULL;}LOCAL freqchain(p)register struct Equivblock *p;{register struct Eqvchain *q, *oq;for(q = p->equivs ; q ; q = oq)	{	oq = q->eqvnextp;	free( (charptr) q);	}p->equivs = NULL;}LOCAL nsubs(p)register struct Listblock *p;{register int n;register chainp q;n = 0;if(p)	for(q = p->listp ; q ; q = q->nextp)		++n;return(n);}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?