aboutsummaryrefslogtreecommitdiffstats
path: root/lcc/cpp/hideset.c
blob: bd2540d48c9404d93f36b5ff4a5023bd47049a43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#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 *)realloc(hidesets, (sizeof (Hideset *))*maxhidesets);
		if (hidesets == NULL)
			error(FATAL, "Out of memory from realloc");
	}
	hs1 = (Hideset)domalloc(len*sizeof(Hideset));
	memmove(hs1, nhs, len*sizeof(Hideset));
	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(Hideset));
	*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, " ");
	}
}