File:  [Research Unix] / researchv10no / cmd / basic / bite / src / savars.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:21:35 2018 UTC (8 years, 1 month ago) by root
Branches: belllabs, MAIN
CVS tags: researchv10, HEAD
researchv10 Norman

/* Copyright Bell Telephone Laboratories Whippany, N.J.

 *	/////////////////////////////////////
 *	/////////////////////////////////////
 *	///////////// savars.c //////////////
 *	/// J. P. Hawkins WH X4610 8C-001 ///
 *	///// Fri Feb 27 06:32:38 1981 //////
 *	/////////////////////////////////////
 *	/////////////////////////////////////
 *	@(#) savars.c: V1.2 3/4/81

 * String array variable Allocation and Fetch routines
 * For BITE
 *
 */
/*   "@(#) savars.c:  V 1.1  2/4/81" */

#include	"bas.h"
/*
 * this is the symbol table (table of pointers) for string array
 * variables. The first subscript 'j' is calculated by the
 * alpha name, the second subscript 'k' is calculated by the
 * numeric part + 1. If no numeric is specified, k = 0
 *
 * The pointer points to an area in memory allocated by dim.
 * The area is of similar form to that of numeric variables
 * except, the pointers to the strings rather than values are
 * actually stored. The header form is the same as that for numeric
 * variables except that the constants a1,a2,a3,..,etc.
 * are unnecessary due to allowing only one or two dimensions.
 * (see remarks at beginning of dim.c module and diagram)
 *
 * The specification for a string array variable is of the form:
 *	Alpha[Numeric]$(a,b)
 * The dimension "dim" statement is specified in the form:
 *	dim Alpha[numeric]$(XMAX[,YMAX])
 * The starting location is obtained by the equation:
 *	Loc = (a-1)*YMAX+b-1
 *
 *	where a <= XMAX
 *	      b <= YMAX
 *
 * If dimension YMAX is not given it is set to 1, however the
 * first byte of the header will specify only one dimension exists.
 *
 */
char *	sasymtab[26][11];
extern	char	*hicore;	/* pointer lowest used corespace from
				    top of user area */


struct FREELIST	 freelist[MAXFREE];
/*
 * //////// FETCH VALUE OF VARIABLE ////////
 *
 * calling format:
 *
 *	sagetvar(sname, &sptr);
 *
 *	where: sname = string containing VALID variable name
 *			i.e. [a-z] or a[0-9] - z[0-9]
 *	       sptr = pointer to string
 */
sagetvar(sname,sptr)
char	sname[];
char	**sptr; /* pointer to string pointer */
{
	char	*addr;

	if(sgetaddr(sname, &addr) < 0)
		return(-1);	/* error occurred in getting addr */

	if(addr == 0)		/*if no pointer for this variable */
				/*  (not allocated, yet) */
	{
		error2(inst.thing.linno,7,' '); /* UNASSIGNED VARIABLE */
		printf("- '%s'\n",sname); /* print variable name */
		*sptr = 0;		/* return zero anyway */
		return(-1);
	}
	else
	{
		*sptr = addr;		/* set ptr to data location */
		*sptr += 1;		/* bump past size byte */
	}
	return(0);
}
/*
 *
 * //// ASSIGN A VALUE TO A VARIABLE ////
 * /////////// ALLOCATE SPACE  //////////
 *
 * Copy the string into the allocated location.
 *
 * calling format:
 *
 *	saputvar(sname, sptr);
 *
 *	where: sname = string pointer to VALID variable name
 *	       sptr = pointer to string to be copied
 */
saputvar(sname,sptr)
char	sname[];	/* valid variable string (name) */
char	*sptr;		/* pointer to string */
{
	register char *ptr,*cptr; /* pointer used for string copy to mem */
	char	*lookfree();
	int	ssize;		/* string size */
	int	useagain;	/* flag to use space again */
	char	*addr;		/* pointer array el. which is ptr to string */

	useagain = 0;
	cptr = sptr;	/* get source string pointer */
	ssize = strlen(sptr);	/* get size of string */
	if(sgetaddr(sname, &addr) < 0)
		return(-1);	/* error occurred in getting addr */
	if(addr != 0)		/* if this variable was used before */
	{
		ptr = addr;		/* point to old space */
		savefree(ptr);		/* save area old in free list */
		if((addr = ptr = lookfree(ssize)) != 0)
			useagain = 1;	/* if other hole is found */
	}
	if(!useagain)	/* if this is the first time this var was used */
	{
		/*
		 * Return error if not enough space left
		 */
		if((hicore - (ssize+2)) <= linptr)
		{
			error(inst.thing.linno, 24); /* NOT ENOUGH ADD. CORE */
			return(-1);
		}
		hicore -= (ssize+2);	/* set new hicore mark - */
					/* include space for null and size */
		ptr = hicore;		/* set pointer for copy */
		*ptr = ssize;		/* put size of 1st string in 1st loc */
		addr = ptr;		/* put new pointer in array table */

		if((unsigned)hicore & 1)	/* hicore to even boundry */
			hicore--;
	}
	ptr++;		/* bump past size */

	while(*ptr++ = *cptr++); /* copy string into storage */

	return(0);
}
#ifdef notdef
/*
 * Return size of string up to first null character
 */
static	strlen(s)
char	*s;
{
	register count;
	for(count = 0; s[count]; count++);
	return(count);
}
#endif
/*
 *
 * Look in freelist to for smallest free area
 * which will fit new allocation. If none, return false.
 * The free list points to previously scrapped areas.
 */
char *
lookfree(size)
{
	register i;
	int	bestsize,besti;

	for(i=0, bestsize=0; i<MAXFREE; i++)
	{
		if(freelist[i].size == 0) /* skip null or deleted entries */
			continue;
		if(freelist[i].size >= size)
		{
			if(bestsize == 0) /* force first fit */
			{
				bestsize = freelist[i].size;
				besti = i;
			}
			else if(freelist[i].size < bestsize) /* better fit? */
			{
				bestsize = freelist[i].size;
				besti = i;
			}
		}
	}
	if(bestsize == 0)
		return(0);	/* nothing found */
	else
	{
		freelist[besti].size = 0;	/* take off free list */
		return(freelist[besti].fraddr);
	}
}

savefree(addr)
char	*addr;
{
	register i;
	int	size;
	int	there;

	size = *addr;
	for(i=0,there=0; i<MAXFREE; i++)
	{
		if((freelist[i].size != 0) && (freelist[i].fraddr == addr))
		{
			/* avoid dup entry */
			there = 1;
			break;
		}
	}
	if(!there)
	{
		for(i=0; i<MAXFREE; i++)
		{
			if(freelist[i].size == 0)
			{
				freelist[i].size = size; /* save size */
				freelist[i].fraddr = addr; /* save address */
				break;
			}
		}
	}
}
/*
 *
 * /// COMPUTE ARRAY VARIABLE ADDRESS ///
 */
sgetaddr(vstr, addr)
char	vstr[];		/* subscripted variable string */
char	**addr;		/* address of subscripted variable pointer */
{
	char	arname[3];	/* array name */
	int	offset;
	int	*ptr;		/* location pointer */
	int	asize;		/* actual array size */
	double	rsize;		/* requested size */
	register i;
	int	j,k;
	double	rdims[MAXDIM];	/* requested dims */
	int	adims[2];	/* actual dims */
	int	amax;		/* max number of dims */

	amax = 2;		/* no more than two dimensions */
	/*
	 * GET ARRAY SYMBOL NAME, NUMBER OF DIMENSIONS &
	 * PUT THE VALUE OF EACH DIMENSION IN DIMLIST
	 */
	if(getdims(vstr,arname,&rsize,rdims) < 0)
		return(-1);
	if(rsize == 1.0)
	{
		rdims[1] = 1.0;
	}
	j = arname[0] - 'a';		/* compute j subscript */

	/*
	 * compute k subscript
	 */
	if(arname[1] == '\0')		/* if no numeric part */
		k = 0;			/* then k = 0th column */
	else
		k = arname[1] - '0' + 1;

	if(sasymtab[j][k] == 0)		/* if not dimensioned complain */
	{
		error(inst.thing.linno, 25); /* NOT DIMENSIONED */
		return(-1);
	}
	ptr = (int *)sasymtab[j][k];		/* point to header */
	asize = *--ptr;				/* get actual size */
	if(asize != (int)rsize)		/* error if mismatch in actual to
					    requested size */
	{
		error(inst.thing.linno, 26); /* WRONG NUM OF DIMS */
		return(-1);
	}
	for(i=0; i<amax; i++)
	{
		adims[i] = *--ptr;
		if((int)rdims[i] > adims[i])
		{
			error(inst.thing.linno, 27); /* DIM > ACTUAL */
			return(-1);
		}
	}
	*--ptr;		/* BASE STARTS AFTER HEADER */
	/*
	 * Note that this structure starts from hi to low memory
 	 *	LOC = BASE - ((a-1)*YMAX+b-1)
	 */
	offset = ((int)rdims[0]-1)*adims[1]+((int)rdims[1]-1);
	*addr = (char *)(ptr-offset);
	return(0);
}

unix.superglobalmegacorp.com

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