111 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			111 lines
		
	
	
		
			1.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
#include <stdio.h>
 | 
						|
#include <stdlib.h>
 | 
						|
#include <string.h>
 | 
						|
#include "cpp.h"
 | 
						|
 | 
						|
/*
 | 
						|
 * A hideset is a null-terminated array of Nlist pointers.
 | 
						|
 * They are referred to by indices in the hidesets array.
 | 
						|
 * Hideset 0 is empty.
 | 
						|
 */
 | 
						|
 | 
						|
#define	HSSIZ	32
 | 
						|
typedef	Nlist	**Hideset;
 | 
						|
Hideset	*hidesets;
 | 
						|
int	nhidesets = 0;
 | 
						|
int	maxhidesets = 3;
 | 
						|
int	inserths(Hideset, Hideset, Nlist *);
 | 
						|
 | 
						|
/*
 | 
						|
 * Test for membership in a hideset
 | 
						|
 */
 | 
						|
int
 | 
						|
checkhideset(int hs, Nlist *np)
 | 
						|
{
 | 
						|
	Hideset hsp;
 | 
						|
 | 
						|
	if (hs>=nhidesets)
 | 
						|
		abort();
 | 
						|
	for (hsp = hidesets[hs]; *hsp; hsp++) {
 | 
						|
		if (*hsp == np)
 | 
						|
			return 1;
 | 
						|
	}
 | 
						|
	return 0;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Return the (possibly new) hideset obtained by adding np to hs.
 | 
						|
 */
 | 
						|
int
 | 
						|
newhideset(int hs, Nlist *np)
 | 
						|
{
 | 
						|
	int i, len;
 | 
						|
	Nlist *nhs[HSSIZ+3];
 | 
						|
	Hideset hs1, hs2;
 | 
						|
 | 
						|
	len = inserths(nhs, hidesets[hs], np);
 | 
						|
	for (i=0; i<nhidesets; i++) {
 | 
						|
		for (hs1=nhs, hs2=hidesets[i]; *hs1==*hs2; hs1++, hs2++)
 | 
						|
			if (*hs1 == NULL)
 | 
						|
				return i;
 | 
						|
	}
 | 
						|
	if (len>=HSSIZ)
 | 
						|
		return hs;
 | 
						|
	if (nhidesets >= maxhidesets) {
 | 
						|
		maxhidesets = 3*maxhidesets/2+1;
 | 
						|
		hidesets = (Hideset *)dorealloc(hidesets, (sizeof (Hideset *))*maxhidesets);
 | 
						|
	}
 | 
						|
	hs1 = (Hideset)domalloc(len*sizeof *hs1);
 | 
						|
	memmove(hs1, nhs, len*sizeof *hs1);
 | 
						|
	hidesets[nhidesets] = hs1;
 | 
						|
	return nhidesets++;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
inserths(Hideset dhs, Hideset shs, Nlist *np)
 | 
						|
{
 | 
						|
	Hideset odhs = dhs;
 | 
						|
 | 
						|
	while (*shs && *shs < np)
 | 
						|
		*dhs++ = *shs++;
 | 
						|
	if (*shs != np)
 | 
						|
		*dhs++ = np;
 | 
						|
	do {
 | 
						|
		*dhs++ = *shs;
 | 
						|
	} while (*shs++);
 | 
						|
	return dhs - odhs;
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
 * Hideset union
 | 
						|
 */
 | 
						|
int
 | 
						|
unionhideset(int hs1, int hs2)
 | 
						|
{
 | 
						|
	Hideset hp;
 | 
						|
 | 
						|
	for (hp = hidesets[hs2]; *hp; hp++)
 | 
						|
		hs1 = newhideset(hs1, *hp);
 | 
						|
	return hs1;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
iniths(void)
 | 
						|
{
 | 
						|
	hidesets = (Hideset *)domalloc(maxhidesets*sizeof(Hideset *));
 | 
						|
	hidesets[0] = (Hideset)domalloc(sizeof *hidesets[0]);
 | 
						|
	*hidesets[0] = NULL;
 | 
						|
	nhidesets++;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
prhideset(int hs)
 | 
						|
{
 | 
						|
	Hideset np;
 | 
						|
 | 
						|
	for (np = hidesets[hs]; *np; np++) {
 | 
						|
		fprintf(stderr, (char*)(*np)->name, (*np)->len);
 | 
						|
		fprintf(stderr, " ");
 | 
						|
	}
 | 
						|
}
 |