#include "cs.h"								/*	AUXFD.C		*/

extern	INSDS	*curip;		/* current insds, maintained by insert.c */

 char *
auxalloc(nbytes,xploc)		/* allocate an auxds, or expand an old one */
 register long  nbytes;		/* caller needs char** spare after xp cell */
 register char **xploc;		/*    call only from init (xxxset) modules */
{
register char *auxp;

	if ((auxp = *xploc) != NULL)      /* if size change only,	     */
		free(auxp);		  /*	free the old space	     */
	else auxrecord(xploc);		  /* else report a new auxds slot    */
	*xploc = auxp = mcalloc(nbytes);  /* now alloc and store the address */
	if (odebug) auxchprint(curip);
	return(auxp);
}

auxrecord(xploc)	      /* put xploc into chain of xp's for this instr */
 register char  **xploc;      /* caller must have char** spare after xp cell */
{				/*	called only from auxalloc	*/
register char	***prvlnk, **nxtloc;

	prvlnk = &curip->auxpchain;		/* from current insds,	*/
	while ((nxtloc = *prvlnk) != NULL)      /* chain through xplocs */
		prvlnk = (char ***)nxtloc + 1;
	*prvlnk = xploc++;			/* then add this xploc	*/
        *xploc = NULL;  		        /* & terminate the chain */
}

fdrecord(fdloc)		      /* put fdloc into chain of fd's for this instr */
 register int  *fdloc;	      /* caller must have 1 int* spare after fd cell */
{				/*	call only from init (xxxset) modules */
register int	**prvlnk, *nxtloc;

	prvlnk = &curip->fdchain;		/* from current insds,	*/
	while ((nxtloc = *prvlnk) != NULL)	/* chain through fdlocs */
		prvlnk = (int **)nxtloc + 1;
	*prvlnk = fdloc++;			/* then add this fdloc	*/
	*(char **)fdloc = NULL; 		/* & terminate the chain */
	if (odebug) fdchprint(curip);
}

fdclose(fdloc)			/* close a file and remove from fd chain */
 register int *fdloc;		/*  call only from inits, after fdrecord */
{
register int	**prvlnk, *nxtloc;

	prvlnk = &curip->fdchain;		/* from current insds,	*/
	while ((nxtloc = *prvlnk) != NULL)    { /* chain through fdlocs */
		if (nxtloc == fdloc) {		/*   till find this one	*/
			close(*fdloc);		/* then close the file	*/
			*fdloc++ = 0;		/*   delete the fd &	*/
			*prvlnk = (int *) *fdloc; /* unlnk from fdchain */
			if (odebug) fdchprint(curip);
			return;
		}
		else prvlnk = (int **)nxtloc + 1;
	}
	fdchprint(curip);
	sprintf(errmsg,"fdclose: no record of fd %d",*fdloc);
	die(errmsg);
}

auxchfree(ip)			/* release all xds in instr auxp chain    */
 register INSDS *ip;		/*   called by insert at orcompact	*/
{
register char	*auxp, **xploc = ip->auxpchain;

	if (odebug) auxchprint(ip);
	do {				  	/* for all xp's in chain: */
		if ((auxp = *xploc) == NULL) {
			auxchprint(ip);
			dies("auxchfree: illegal xdsp %x in chain",auxp);
		}
		free(auxp);			/*	free the space	*/
		*xploc++ = NULL;		/*	& delete the pntr */
	}
	while ((xploc = (char **) *xploc) != NULL);
	ip->auxpchain = NULL;   		/* finally, delete the chain */
	if (odebug) auxchprint(ip);
}

fdchclose(ip)			/* close all files in instr fd chain     */
 register INSDS *ip;		/*   called by insert on deact & expire  */
{			/*   (also musmon on s-code, & fgens for gen01)	 */
register int	fd, *fdloc = ip->fdchain;

	if (odebug) fdchprint(ip);
	do {				  	/* for all fd's in chain: */
		if ((fd = *fdloc) <= 2) {
			fdchprint(ip);
			sprintf(errmsg,"fdclose: illegal fd %d in chain",fd);
			die(errmsg);
		}
		close(fd);			/*	close the file	*/
		*fdloc++ = 0;			/*	& delete the fd	*/
	}
	while ((fdloc = (int *) *fdloc) != NULL);
	ip->fdchain = (int *)0;			/* finally, delete the chain */
	if (odebug) fdchprint(ip);
}

auxchprint(ip)			/* print the xp chain for this insds blk */
 register INSDS *ip;
{
register char	***prvlnk, **nxtloc;

	printf("auxlist for instr %d (%x):", ip->insno, ip);
	prvlnk = &ip->auxpchain;		     /* for this insds,	*/
	while ((nxtloc = *prvlnk) != NULL) {         /* chain through xplocs */
		printf("  auxp %x in %x",*nxtloc,nxtloc);
		prvlnk = (char ***)nxtloc + 1;
	}
	putchar('\n');
}

fdchprint(ip)			/* print the fd chain for this insds blk */
 register INSDS *ip;
{
register int	**prvlnk, *nxtloc;

	printf("fdlist for instr %d (%x):", ip->insno, ip);
	prvlnk = &ip->fdchain;			/* for this insds,	*/
	while ((nxtloc = *prvlnk) != NULL) {    /* chain through fdlocs */
		printf("  fd %d in %x",*nxtloc,nxtloc);
		prvlnk = (int **)nxtloc + 1;
	}
	putchar('\n');
}
