File:  [Power 6/32 Unix Tahoe 4.2BSD] / cci / usr / src / bin / cdb / ty.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Sun Jul 28 12:24:19 2019 UTC (7 years ago) by root
Branches: bsd, MAIN
CVS tags: v12b, v121, HEAD
Power 6/32 Unix version 1.2b

static char sccsid[] = "@(#)ty.c	2.16";

#include <ctype.h>
#include "cdb.h"
#include "macdefs.h"

#ifdef BSD41
#define crockValue -1
#define cbSbSafe 1024
#else
#define crockValue ""
#define cbSbSafe 256
#endif
char	vsbSafe[cbSbSafe];	/* where we stick names of things */
char	*vsbNextSafe = vsbSafe;	/* next available place */

/*			                   v - that is the fConstant field */
#ifdef SUN
TYR	atyCnChar = {
	crockValue,  stValue, true,  0, 0,0,0,0,0,0, btChar,  0};
TYR	atyChar =   {
	crockValue,  stValue, false, 0, 0,0,0,0,0,0, btChar,  0};
TYR	atyCnShort ={
	crockValue,  stValue, true,  0, 0,0,0,0,0,0, btShort, 0};
TYR	atyShort =  {
	crockValue,  stValue, false, 0, 0,0,0,0,0,0, btShort, 0};
TYR	atyCnInt =  {
	crockValue,  stValue, true,  0, 0,0,0,0,0,0, btInt,   0};
TYR	atyInt =    {
	crockValue,  stValue, false, 0, 0,0,0,0,0,0, btInt,   0};
TYR	atyCnLong = {
	crockValue,  stValue, true,  0, 0,0,0,0,0,0, btLong,  0};
TYR	atyLong =   {
	crockValue,  stValue, false, 0, 0,0,0,0,0,0, btLong,  0};
TYR	atyCnFloat ={
	crockValue,  stValue, true,  0, 0,0,0,0,0,0, btFloat, 0};
TYR	atyFloat =  {
	crockValue,  stValue, false, 0, 0,0,0,0,0,0, btFloat, 0};
#else
TYR	atyCnChar = {
	crockValue,  stValue, true,  0, btChar,  0,0,0,0,0,0, 0};
TYR	atyChar =   {
	crockValue,  stValue, false, 0, btChar,  0,0,0,0,0,0, 0};
TYR	atyCnShort ={
	crockValue,  stValue, true,  0, btShort, 0,0,0,0,0,0, 0};
TYR	atyShort =  {
	crockValue,  stValue, false, 0, btShort, 0,0,0,0,0,0, 0};
TYR	atyCnInt =  {
	crockValue,  stValue, true,  0, btInt,   0,0,0,0,0,0, 0};
TYR	atyInt =    {
	crockValue,  stValue, false, 0, btInt,   0,0,0,0,0,0, 0};
TYR	atyCnLong = {
	crockValue,  stValue, true,  0, btLong,  0,0,0,0,0,0, 0};
TYR	atyLong =   {
	crockValue,  stValue, false, 0, btLong,  0,0,0,0,0,0, 0};
TYR	atyCnFloat ={
	crockValue,  stValue, true,  0, btFloat, 0,0,0,0,0,0, 0};
TYR	atyFloat =  {
	crockValue,  stValue, false, 0, btFloat, 0,0,0,0,0,0, 0};
#endif
TYR	atyZeros;

export pTYR	vtyZeros;
export pTYR	vtyChar, vtyCnChar;
export pTYR	vtyShort, vtyCnShort;
export pTYR	vtyInt, vtyCnInt;
export pTYR	vtyLong, vtyCnLong;
export pTYR	vtyFloat, vtyCnFloat;

/* most of this type code is NOT needed if we have berkely symbol tables */
#ifndef BSD41
export int	vityMac;	/* # TY's in current decl file */
int	vityBase, vityLim;	/* bounds on the ty cache */
int	vcTyCache;		/* # of things actually in cache */
#define cTyCacheMax	100
TYR	vtyCache[cTyCacheMax];	/* buffer where we stick type stuff */
int	vity;		/* index of TY of current interest */
pTYR	vtyCur;		/* TY of current interest */
#define cbTyCache sizeof(vtyCache)

#define fDoForward	true
#define fDoBackward	false

/* S E T   T Y   C A C H E */

local void SetTyCache(ity)
int	ity;
{
	int		ityTemp, cRead;
	long	l1, l2, offset;

	if ( ((ity >= vityBase) AND (ity < vityLim-(cTyMax-1)))
	    OR ((ity == vityLim-(cTyMax-1)) AND (vityLim == vityMac)) ) {
		return;	/* it is already in there, somewhere */
	} /* if */
	ityTemp = (ity / cTyCacheMax) * cTyCacheMax; /* adjust to 'page' boundary */
	if ((ity+(cTyMax-1)) % cTyCacheMax == 0)
		ityTemp += (cTyMax-1);	/* allow room for a possible second TYR */
	l1 = ityTemp;
	l2 = cbTYR;
	offset = l1 * l2;
	if (lseek(vfnDecl, offset, 0) < 0L) {
		Panic("Bad seek in SetTyCache");
	} /* if */
	if ((cRead=read(vfnDecl, vtyCache, cbTyCache)) < 0)
		Panic("Bad read in SetTyCache");
	vcTyCache = cRead / cbTYR;
	vityBase = ityTemp;
	vityLim = vityBase + vcTyCache;
} /* SetTyCache */


/* S E T   T Y */

local void SetTy(ity)
int	ity;
{
	if (ity < 0 OR ity >= vityMac)
		Panic("ity out of bounds in SetTy - %d", ity);
	vity = ity;
	SetTyCache(ity);
	vtyCur = vtyCache + (ity-vityBase);
} /* SetTy */


/* S E T   T Y   N E X T */

local void SetTyNext(ity, fForward)
FLAGT	fForward;
{
	if ((ity < 0) OR (ity >= vityMac))
		Panic("ity out of bounds in SetTyNext - %d", ity);
	vity = ity + ((fForward) ? -1 : 1);
	if (vity < 0)
		vity = 0;
	else if (vity >= vityMac)
		vity = vityMac - 1;
	SetTy(vity);
} /* SetTyNext */


/* F   N E X T   T Y */

local FLAGT FNextTy(fForward, sbVar, stLook1, stLook2, stStop1, stStop2)
FLAGT	fForward;
char	*sbVar;
int	stLook1, stLook2, stStop1, stStop2;
{
	int		i, st, ityEnd, dity, ity;

	if (vityMac == 0)
		return(false);	/* there is no valid decl file open */
	dity = (fForward) ? 1 : -1;
	ity = vity + dity;
	while ((ity >= 0) AND (ity < vityMac)) {
		SetTyCache(ity);
		ityEnd = (fForward) ? vityLim : vityBase-1;
		for (i = ity; ity != ityEnd; i+=dity, ity+=dity) {
			vtyCur = vtyCache + i;
			st = vtyCur->td.st & 0x00ff;
			if (  (st == stLook1)
			    OR (st == stLook2)
			    OR ((sbVar != sbNil)
			    AND (stLook1 == 0)
			    AND (stLook2 == 0))) {
				if ((sbVar == sbNil)
				    OR (FProcCmp(vtyCur->sbVar, sbVar)) ) {
					SetTy(ity);
					return(true);
				} /* if */
			} 
			else if (st == stStop1 OR st == stStop2) {
				return(false);
			} /* if */
		} /* for */
	} /* while */
	return(false);
} /* FNextTY */


/* I T Y   F   S B   L N */

local int ItyFSbLn(sbVar, ln)
char	*sbVar;
int	ln;
{
	int		ity;
	FLAGT	fFoundBlock;

	if ((vfnDecl == fnNil)
	    OR (ln <= 0))
		return(ityNil);

	/* first we find a block mark with a line number GREATER than ln */
	SetTyNext(0, fDoForward);
	fFoundBlock = false;
	while (FNextTy(fDoForward, sbNil, stLBrac, stRBrac, 0, 0)) {
		if (vtyCur->valTy > ln) {
			fFoundBlock = true;
			break;
		} /* if */
	} /* while */
	if (!fFoundBlock) {
		/* this could happen when looking for a formal of the
			 * last procedure in a file, and the procedure does not have
			 * any locals.
			 */
		ity = vityMac-1;	/* this might not be quite right - kludge */
		SetTyNext(ity, fDoBackward);
	} /* if */

	/* now we back up and find the name (if it's there) */
	if (FNextTy(fDoBackward, sbVar, 0, 0, 0, 0)) {
		return(vity);
	} /* if */
	return(ityNil);
} /* ItyFSbLn */


/* I N I T   T Y   C A C H E */

export void InitTyCache()
{
	vityBase = 0;
	vityLim = 0;
	SetTyCache(0);
} /* InitTyCache */
#endif


/* S B   S A F E */

export SBT SbSafe(sb)
char	*sb;
{
	int		i;
	SBT		sbRet;
	char	*sbT;

	/* this guy sticks names in a temporarily safe place */
	/* find the null or : */
	for (sbT = sb; *sbT != chNull; sbT++)
		if (*sbT == ':')
			break;
	i = sbT - sb + 1;
	if (vsbNextSafe+i >= vsbSafe+cbSbSafe)
		/* would run off end of buffer */
		vsbNextSafe = vsbSafe;	/* reuse the buffer */
	strncpy(vsbNextSafe, sb, i);
#ifdef BSD41
	sbRet = bitHigh | (SBT)vsbNextSafe;
#else
	sbRet = vsbNextSafe;
#endif
	vsbNextSafe[i-1] = chNull;
	vsbNextSafe += i;
	return(sbRet);
} /* SbSafe */


/* S B   I N   S A F E */

export char * SbInSafe(iss)
long	iss;
{
	return( SbInCore(SbSafe(SbInCore(iss))) );
}


#ifdef BSD42

/* I S S   F   I D B */

local long IssFIdb(idb, iss)
int	idb;
long	iss;
{
	int		ifd, cbTarget;
	long	isym, issMac;
	char	*sbSym, *sbT1, *sbT2, sbIdb[10];

	/* given a DBX type number and a maximum iss, find the
	     * definition of the type.
	     * Return the index into string space.
	     */

	/* first we find beginning of THIS file's symbols */
	issMac = iss + 1;
	ifd = vifdNil;
	if (vifd != vifdNil) {
		SetSym(vrgFd[vifd].isym);
		if (vsymCur->sbSym < issMac) {
			SetSym(vrgFd[vifd+1].isym);
			if (vsymCur->sbSym >= issMac)
				ifd = vifd;
		}
	}
	if (ifd == vifdNil) {
		for (ifd=0; ifd < vifdMac; ifd++) {
			SetSym(vrgFd[ifd].isym);
			if (vsymCur->sbSym >= issMac) {
				ifd--;
				break;
			}
		} /* for */
	} /* if */
	sprintf(sbIdb, "%d", idb);
	cbTarget = strlen(sbIdb);
	isym = vrgFd[ifd].isym
#ifdef SUN
	    + 12;	/* skip file sym + standard 11 types*/
#else
	+ 13;	/* skip file sym + standard 12 types*/
#endif
	SetSym(isym);
	while (vsymCur->sbSym < issMac) {
		sbT1 = sbSym = SbInCore(vsymCur->sbSym);
		while ((sbT2 = strchr(sbT1, '=')) != sbNil) {
			/* a cadidate */
			if (FHdrCmp(sbIdb, sbT2-cbTarget)) {
				/* found it! */
				return(vsymCur->sbSym + (1+(sbT2-sbSym)));
			}
			sbT1 = sbT2 + 1; /* move past '=', see if there is another one */
		} /* while */
		isym++;
		SetSym(isym);
	} /* while */
	Panic("Can't find idb: %d in ifd: %d", idb, ifd);
} /* IssFIdb */


/* T Y   F   I D B */

local void TyFIdb(rgTy, idb)
pTYR	rgTy;
int	idb;
{
	int		bt;
	/* these are the standard DBX types */
	switch (idb) {
	case 1:	
		bt = btInt;	
		break;
	case 2:	
		bt = btChar;	
		break;
	case 3:	
		bt = btLong;	
		break;
	case 4:	
		bt = btShort;	
		break;
	case 5:	
		bt = btUChar;	
		break;
	case 6:	
		bt = btUShort;	
		break;
	case 7:	
		bt = btULong;	
		break;
	case 8:	
		bt = btUInt;	
		break;
	case 9:	
		bt = btFloat;	
		break;
	case 10: 
		bt = btDouble; 
		break;
	case 11: 
		bt = btNil; 
		break;
	} /* switch */
	rgTy->td.bt = bt;
} /* TyFIdb */


/* I S S   F   S T A R T */

export long IssFStart(iss)
{
	char 	*sb;
	/* given an iss at the beginning of a struct, union or enum definition
	     * return the iss of the NAME of this thing
	     * We have something like "FOOR:t18=s12....." and iss is pointing
	     * at the 's' after the '='.
	     */
	do {
		sb = SbInCore(--iss);
	} 
	while ((*sb != chNull) AND (*sb != ';'));
	return(++iss);
} /* IssFStart */


/* T Y   F   S C A N   D B X */

local void TyFScanDbx(rgTy, iss)
pTYR	rgTy;
long	iss;
{
	int		i, idb;
	char	ch;
	char	*sb;
	pXTYR	xty;

	printf("TyFScanDBX caled with 0x%x and %d\n",rgTy, iss);
	xty = (pXTYR) (rgTy + 1); /* in case anyone needs it */
	while (true) {
		sb = SbInCore(iss);
		printf("-1- sb :%s:\n",sb);
		ch = *sb;
		switch (ch) {
		case chNull:
		case ',':
		case ';':
			return;
		case '0': 
		case '1': 
		case '2': 
		case '3': 
		case '4':
		case '5': 
		case '6': 
		case '7': 
		case '8': 
		case '9':
			idb = atoi(sb);
			printf("-2- idb : %d\n",idb);
			while (isdigit(*sb)) {
				sb++;
				iss++;
			}
			printf("-3- iss:%d sb:%s:\n", iss,sb);
			if (*sb == '=')
				break;	/* continue onwards */
			if (idb <= 11) {
				TyFIdb(rgTy, idb);
				return;
			} 
			else {
				iss = IssFIdb(idb, iss);
			}
			continue;
			break;
		case '*':
			FAdjTd(rgTy, tqPtr);
			break;
		case '=':
			break;
		case 'a':
			/* we expect this to look like 'ar1;0;#1;#2;
					 * where 0 is the lower bounds (always for C),
					 *       #1 is the upper bound,
					 *	 #2 is the element type (possibley another array)
					 */
			sb++;
			if ((*sb++ != 'r')
			    OR (*sb++ != '1')
			    OR (*sb++ != ';')
			    OR (*sb++ != '0')
			    OR (*sb++ != ';'))
				Panic("Lost in array spec??");
			iss += 6;
			i = atoi(sb);	/* get the size of the dimension */
			while (isdigit(*sb) OR (*sb == '-')) {
				sb++;
				iss++;
			}
			if (*sb++ != ';')
				Panic("Lost in array spec");
			if (xty->rgDim[1] == 0) {
				if (TqFTy(rgTy, 1) != tqArray)
					FAdjTd(rgTy, tqArray);
				xty->st = stExtend;
				if (xty->rgDim[0] == 0)
					xty->rgDim[0] = i;
				else
					xty->rgDim[1] = i;
			}
			/* we should have sb pointing at the type number.
					 * loop will continue and go find it for us.
					 */
			break;
		case 'e':
			rgTy[0].td.bt = btEType;
			xty->st = stExtend;
			xty->issRef = IssFStart(iss);
			return;
		case 'f':
		case 'F':
			rgTy[0].td.st = stProc;
			break;
		case 'G':
			rgTy[0].td.st = stGlobal;
			break;
		case 'v':	/* 'vaires' parameter - i.e. REFerenced */
		case 'p':
			rgTy[0].td.st = stParam;
			break;
		case 'r':	/* I don't know what this means!!! */
			break;
		case 'V':	/* 'local' static */
		case 'S':	/* 'global' static */
			rgTy[0].td.st = stStatic;
			break;
		case 's':
		case 'u':
			rgTy[0].td.bt = (ch == 's') ? btStruct : btUnion;
			xty->st = stExtend;
			xty->issRef = IssFStart(iss);
			xty->cb = atoi(++sb);	/* size in bytes */
			return;
		case 'T':	/* tag - named type */
		case 't':	/* type */
			break;
		} /* switch */
		iss++;
	} /* while */
} /* TyFScanDbx */


/* T Y   F   4 2 */

export void TyF42(rgTy, isym)
pTYR	rgTy;
long	isym;
{
	char	*sb, *sbStart;
	long	iss;
	pTYR	ty;

	SetSym(isym);
	iss = vsymCur->sbSym;
	sbStart = SbInCore(iss);
	sb = strchr(sbStart, ':');
	if (sb == sbNil) {
		/* sdb symbol - what you see is what you get */
		rgTy[0] = *((pTYR) vsymCur);
		SetSym(isym+1);
		rgTy[1] = *((pTYR) vsymCur);
	} 
	else {
		/* dbx symbol */
		ty = (pTYR) vsymCur;
		rgTy[0] = rgTy[1] = *vtyZeros;
		rgTy->sbVar = SbSafe(sbStart);	/* copies up to ':' */
		rgTy->td.st = ty->td.st;
		rgTy->valTy = ty->valTy;
		iss += sb - sbStart;
		TyFScanDbx(rgTy, iss, isym);
		SetSym(isym);
	}
} /* TyF42 */


/* T Y   F   F I E L D */

local void TyFField(ty, iss)
pTYR	ty;
long	iss;
{
	int		i, offset, width;
	char	*sbF, *sbS, sbTemp[100];

	/* somewhere in this symbol is the field info, stuff it in ty */
	sbF = SbInCore(ty->sbVar);
	sprintf(sbTemp, "%s:", sbF);
	sbS = SbInCore(iss);
	i = IFSbSb(sbS, sbTemp);	/* moving window search */
	if ((i == -1)
	    OR ((sbS[i-1] != ';') AND (!isdigit(sbS[i-1]))) )
		return;	/* caller can detect fact because ty->td.bt == btNil */
	iss += i + strlen(sbTemp);
	TyFScanDbx(ty, iss);	/* this will build the type info */
	sbS = 1 + strchr(SbInCore(iss), ',');
	sscanf(sbS,"%d,%d", &offset, &width);
	if (((ty->td.bt == btUInt) AND (width != SZINT))
	    OR ((offset % SZCHAR) != 0)
	    OR ((width % SZCHAR) != 0)) {
		/* this MUST be a bit field */
		if ((ty->td.bt != btUInt) OR (width > SZINT))
			Panic("Confused looking at bit field %s @ %ld", sbF, iss);
		ty->td.width = width;
		ty->td.bt = btUInt;
		ty->valTy = offset;
	} 
	else {
		ty->td.width = 0;
		ty->valTy = offset / SZCHAR;
	}
} /* TyFField */


/* T Y   F   L O O K U P */

local void TyFLookup(tyStruct, tyField)
pTYR	tyStruct, tyField;
{
	long	iss;
	pXTYR	xty;

	/* given a structure, see if the field is a member. If so,
	     * return its type stuff.  If not, see if we can find a
	     * field by this name and use it.  This search is user
	     * selectable.
	     */
	if ( ((tyStruct->td.bt == btStruct) OR (tyStruct->td.bt == btUnion))
	    AND (tyStruct[1].td.st == stExtend) ) {
		xty = (pXTYR) (tyStruct+1);
		iss = xty->issRef; /* this is already absolute because of TyFScanDbx */
		TyFField(tyField, iss);
		if (tyField->td.bt != btNil)
			return;
		UError("No such field name %s for %s %s",
		SbInSafe(tyField->sbVar),
		(tyStruct->td.bt==btStruct) ? "struct" : "union",
		SbInSafe(iss) );
	}

	/* we get here if it wasn't a structure, OR it did not have a field
	     * name as referenced.  We will now go looking for something reasonable.
	     * We do not currently do the scan. This means you can't reference
	     * a field name not part of the appropriate struct/union.
	     */

} /* TyFLookup */


#endif

/* ------------------ Back to normal ------------------------ */


/* I N I T   T Y */

export void InitTy()
{
	/* set up standard type descriptors */
	vtyZeros = &atyZeros;
	vtyCnChar = &atyCnChar;
	vtyChar = &atyChar;
	vtyCnShort = &atyCnShort;
	vtyShort = &atyShort;
	vtyCnInt = &atyCnInt;
	vtyInt = &atyInt;
	vtyCnLong = &atyCnLong;
	vtyLong = &atyLong;
	vtyCnFloat = &atyCnFloat;
	vtyFloat = &atyFloat;
} /* InitTy */


/* F   I N T   F   T Y */

export FLAGT FIntFTy(ty)
pTYR	ty;
{
	if (tqPtr == TqFTy(ty, 1))
		return(true);
	switch (ty->td.bt) {
	case btInt:
	case btUInt:
	case btUShort:
	case btShort:
	case btLong:
	case btULong:
	case btChar:
	case btUChar:
	case btFArg:	/* is this one right??? - kludge */
	case btEMember:	
		return(true);
	case btNil:
	case btFloat:
	case btDouble:
	case btEType:
	case btUnion:
	case btStruct:	
		return(false);
	} /* switch */
	return(false);
} /* FIntFTy */


/* M A X   F   T Y   T Y */

export FLAGT MaxFTyTy(rgTyMax, rgTy1, rgTy2)
pTYR	rgTyMax, rgTy1, rgTy2;
{
	if (FIntFTy(rgTy1) AND FIntFTy(rgTy2)) {
		if (CbFTy(rgTy1) >= CbFTy(rgTy2))
			CopyTy(rgTyMax, rgTy1);
		else
			CopyTy(rgTyMax, rgTy2);
		return(true);
	} /* if */
	return(false);
} /* MaxFTyTy */


/* C O P Y   T Y */

export void CopyTy(tyDest, tySrc)
pTYR	tyDest, tySrc;
{
	*tyDest++ = *tySrc++;
	*tyDest = *tySrc;
} /* CopyTy */


/* T Y   F   G L O B A L */

export void TyFGlobal(rgTy, sbVar)
pTYR	rgTy;
char	*sbVar;
{

#ifdef SYSIII
	if (vfnDecl != fnNil) {
		SetTyNext(vityMac-1, fDoBackward);
		if (FNextTy(fDoBackward, sbVar, 0, 0, 0, 0)) {
			CopyTy(rgTy, vtyCur);
			return;
		} /* if */
	} /* if */
	rgTy[0] = *vtyInt;	/* this could easily be WRONG! */
	strncpy(rgTy[0].sbVar, sbVar, 8);
#endif
#ifdef BSD41
	long	isymSave;
	pTYR	ty;

	isymSave = visym;
	SetSym(isym0);
	if (FNextSym(stGlobal, stStatic, 0, sbVar, FProcCmp)) {
#ifdef BSD42
		TyF42(rgTy, visym);
#else
		ty = (pTYR) vsymCur;
		rgTy[0] = *ty;
		SetSym(visym+1);
		ty = (pTYR) vsymCur;
		rgTy[1] = *ty;
#endif
	} 
	else {
		rgTy[0] = *vtyInt;
	} /* if */
	SetSym(isymSave);
#endif
} /* TyFGlobal */


/* T Y   F   L O C A L */

export void TyFLocal(rgTy, sbVar, isym)
pTYR	rgTy;
char	*sbVar;
long	isym;
{

#ifdef BSD41
	/* with BSD symbols, the location info for locals is same sym as type */
	long	isymSave;
	pTYR	ty;

	isymSave = isym;
#ifdef BSD42
	TyF42(rgTy, isym);
#else
	SetSym(isym);
	ty = (pTYR) vsymCur;
	rgTy[0] = *ty;
	SetSym(visym+1);
	ty = (pTYR) vsymCur;
	rgTy[1] = *ty;
#endif
	SetSym(isymSave);
#else
	int		cb, ln, ity;
	long	isymSave;

	isymSave = isym;
	ln = IlnFIsym(isym);
	if ( (vfnDecl == fnNil)
	    OR ((ity = ItyFSbLn(sbVar, ln)) == ityNil) ) {
		cb = CbFLocal(isym);
		SetSym(isymSave);
		if (cb == 1)
			CopyTy(rgTy, vtyChar);
		else if (cb != 4)
			CopyTy(rgTy, vtyInt);
		else 
		    CopyTy(rgTy, vtyLong);
		/* this could easily be WRONG! */
	} 
	else {
		SetSym(isymSave);
		SetTy(ity);
		CopyTy(rgTy, vtyCur);
	} /* if */
	rgTy->td.st = stValue;
	if (vsymCur->type == N_REG)
		rgTy->td.st = stReg;
	else if (FHdrCmp(vsbProcHdr, vsymCur->sbSym))
		rgTy->td.st = stProc;
	strncpy(rgTy->sbVar, sbVar, cbVarMax-1);
	rgTy->sbVar[cbVarMax-1] = chNull;
#endif
} /* TyFLocal */


/* T Q   F   T Y */

export int TqFTy(ty, cnt)
pTYR	ty;
int	cnt;
{
#ifdef REGULUS
	return(tqNil);
#else
	switch (cnt) {
	case 1:	
		return(ty->td.tq1);
	case 2:	
		return(ty->td.tq2);
	case 3:	
		return(ty->td.tq3);
	case 4:	
		return(ty->td.tq4);
	case 5:	
		return(ty->td.tq5);
	case 6:	
		return(ty->td.tq6);
	} /* switch */
#endif
} /* TqFTy */


/* F   A D J   T D */

export FLAGT FAdjTd(ty, tq)
pTYR	ty;
int	tq;
{
	pTDR	td;
#ifdef REGULUS
	return(true);
#else
	td = &(ty->td);
	if (tq != tqNil) {
		if (td->tq6 != tqNil) {
			/* all seats are taken */
			return(false);
		} 
		else {
			td->tq6 = td->tq5;
			td->tq5 = td->tq4;
			td->tq4 = td->tq3;
			td->tq3 = td->tq2;
			td->tq2 = td->tq1;
			td->tq1 = tq;
		} /* if */
	} 
	else {
		td->tq1 = td->tq2;
		td->tq2 = td->tq3;
		td->tq3 = td->tq4;
		td->tq4 = td->tq5;
		td->tq5 = td->tq6;
		td->tq6 = tqNil;
	} /* if */
	return(true);
#endif
} /* FAdjTd */


/* C B   F   T Y */

export int CbFTy(ty)
pTYR	ty;
{
	int		tq;
	pXTYR	xty;

	if (ty == tyNil)
		return(0);

	if (ty->td.width != 0)
		return(-1);	/* a bit field */

	tq = TqFTy(ty, 1);
	if (tq != tqNil)
		return(CBPOINT);	/* treat it as a pointer */

	switch (ty->td.bt) {
	case btNil:	
		return(0);
	case btInt:
	case btUInt:	
		return(CBINT);
	case btUShort:
	case btShort:	
		return(CBSHORT);
	case btLong:
	case btULong:	
		return(CBLONG);
	case btChar:
	case btUChar:	
		return(1);
	case btFloat:	
		return(CBFLOAT);
	case btDouble:	
		return(CBDOUBLE);
	case btFArg:
	case btEType:
	case btEMember:	
		return(CBINT);
	case btUnion:
	case btStruct:	
		/* the following boils down to 'if !BSD41 OR (BSD41 AND !BSD42)' */
#ifdef BSD41
#ifndef BSD42
		if (ty[1].td.st != stLeng)
			return(CBINT);
		return(ty[1].valTy);
#else
		if (ty[1].td.st != stExtend) {
			if (ty[1].td.st == stLeng)
				return(ty[1].valTy);
			else
				return(CBINT);
		}
		xty = (pXTYR) (ty + 1);
		return(xty->cb);
#endif
#else
		if (ty[1].td.st != stExtend) {
			if (ty[1].td.st == stLeng)
				return(ty[1].valTy);
			else
				return(CBINT);
		}
		xty = (pXTYR) (ty + 1);
		return(xty->cb);
#endif
	} /* switch */
	return(0);
} /* CbFTy */


/*  A D R   F   F I E L D */

export long AdrFField(adrLong, tyStruct, tyField)
long	adrLong;
pTYR	tyStruct, tyField;
{
	long	isymSave;
	char	*sbField;
	pTYR	ty;
	int		issSave;

#ifdef BSD41
	issSave = tyField[0].sbVar;	/* wipe everything clean but the name */
	tyField[0] = *vtyZeros;
	tyField[1] = *vtyZeros;
	tyField[0].sbVar = issSave;
#ifdef BSD42
	TyFLookup(tyStruct, tyField);	/* does all the 4.2 crap */
#endif
	if (tyField[0].td.bt == btNil) {
		/* this SUCKS! It is because <4.2 Berkeley compilers have
		     * neanderthal ideas about binding (ie. they don't) field
		     * names to the parent structure.
		     */
		isymSave = visym;
		sbField = SbInSafe(tyField->sbVar);
		SetSym(vrgFd[vifd].isym);
		if (!FNextSym(stStruct, 0, stSource, sbField, FProcCmp))
			if (vfPascal)
				UError("Sorry, Berkeley Pascal does not give me the field names");
			else
				UError("No such field name: %s", sbField);
		ty = (pTYR) vsymCur;
		tyField[0] = *ty;
		SetSym(visym+1);
		ty = (pTYR) vsymCur;
		tyField[1] = *ty;
		SetSym(isymSave);
		if (tyField->td.st != stStruct)
			UError("'%s' is not a field name", SbInCore(tyField->sbVar));
	} /* if */

	if (tyField->td.width != 0) {
		adrLong += tyField->valTy / SZCHAR; /* set to nearest byte boundary */
		tyField->valTy %= SZCHAR;
	} 
	else {
		adrLong += tyField->valTy;	/* add its offset to base address */
	}
	return(adrLong);
#endif
} /* AdrFField */

unix.superglobalmegacorp.com

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