xref: /plan9/sys/src/cmd/9nfs/string.c (revision 9a747e4fd48b9f4522c70c07e8f882a15030f964)
1*9a747e4fSDavid du Colombier #include "all.h"
2*9a747e4fSDavid du Colombier 
3*9a747e4fSDavid du Colombier #define STRHASH	509	/* prime */
4*9a747e4fSDavid du Colombier 
5*9a747e4fSDavid du Colombier static Strnode *	stab[STRHASH];
6*9a747e4fSDavid du Colombier 
7*9a747e4fSDavid du Colombier static long	hashfun(void*);
8*9a747e4fSDavid du Colombier static Strnode*	nalloc(int);
9*9a747e4fSDavid du Colombier 
10*9a747e4fSDavid du Colombier char *
strfind(char * a)11*9a747e4fSDavid du Colombier strfind(char *a)
12*9a747e4fSDavid du Colombier {
13*9a747e4fSDavid du Colombier 	Strnode **bin, *x, *xp;
14*9a747e4fSDavid du Colombier 
15*9a747e4fSDavid du Colombier 	bin = &stab[hashfun(a) % STRHASH];
16*9a747e4fSDavid du Colombier 	for(xp=0, x=*bin; x; xp=x, x=x->next)
17*9a747e4fSDavid du Colombier 		if(x->str[0] == a[0] && strcmp(x->str, a) == 0)
18*9a747e4fSDavid du Colombier 			break;
19*9a747e4fSDavid du Colombier 	if(x == 0)
20*9a747e4fSDavid du Colombier 		return 0;
21*9a747e4fSDavid du Colombier 	if(xp){
22*9a747e4fSDavid du Colombier 		xp->next = x->next;
23*9a747e4fSDavid du Colombier 		x->next = *bin;
24*9a747e4fSDavid du Colombier 		*bin = x;
25*9a747e4fSDavid du Colombier 	}
26*9a747e4fSDavid du Colombier 	return x->str;
27*9a747e4fSDavid du Colombier }
28*9a747e4fSDavid du Colombier 
29*9a747e4fSDavid du Colombier char *
strstore(char * a)30*9a747e4fSDavid du Colombier strstore(char *a)
31*9a747e4fSDavid du Colombier {
32*9a747e4fSDavid du Colombier 	Strnode **bin, *x, *xp;
33*9a747e4fSDavid du Colombier 	int n;
34*9a747e4fSDavid du Colombier 
35*9a747e4fSDavid du Colombier 	bin = &stab[hashfun(a) % STRHASH];
36*9a747e4fSDavid du Colombier 	for(xp=0, x=*bin; x; xp=x, x=x->next)
37*9a747e4fSDavid du Colombier 		if(x->str[0] == a[0] && strcmp(x->str, a) == 0)
38*9a747e4fSDavid du Colombier 			break;
39*9a747e4fSDavid du Colombier 	if(x == 0){
40*9a747e4fSDavid du Colombier 		n = strlen(a)+1;
41*9a747e4fSDavid du Colombier 		x = nalloc(n);
42*9a747e4fSDavid du Colombier 		memmove(x->str, a, n);
43*9a747e4fSDavid du Colombier 		x->next = *bin;
44*9a747e4fSDavid du Colombier 		*bin = x;
45*9a747e4fSDavid du Colombier 	}else if(xp){
46*9a747e4fSDavid du Colombier 		xp->next = x->next;
47*9a747e4fSDavid du Colombier 		x->next = *bin;
48*9a747e4fSDavid du Colombier 		*bin = x;
49*9a747e4fSDavid du Colombier 	}
50*9a747e4fSDavid du Colombier 	return x->str;
51*9a747e4fSDavid du Colombier }
52*9a747e4fSDavid du Colombier 
53*9a747e4fSDavid du Colombier void
strprint(int fd)54*9a747e4fSDavid du Colombier strprint(int fd)
55*9a747e4fSDavid du Colombier {
56*9a747e4fSDavid du Colombier 	Strnode **bin, *x;
57*9a747e4fSDavid du Colombier 
58*9a747e4fSDavid du Colombier 	for(bin = stab; bin < stab+STRHASH; bin++)
59*9a747e4fSDavid du Colombier 		for(x=*bin; x; x=x->next)
60*9a747e4fSDavid du Colombier 			fprint(fd, "%ld %s\n", bin-stab, x->str);
61*9a747e4fSDavid du Colombier }
62*9a747e4fSDavid du Colombier 
63*9a747e4fSDavid du Colombier static long
hashfun(void * v)64*9a747e4fSDavid du Colombier hashfun(void *v)
65*9a747e4fSDavid du Colombier {
66*9a747e4fSDavid du Colombier 	ulong a = 0, b;
67*9a747e4fSDavid du Colombier 	uchar *s = v;
68*9a747e4fSDavid du Colombier 
69*9a747e4fSDavid du Colombier 	while(*s){
70*9a747e4fSDavid du Colombier 		a = (a << 4) + *s++;
71*9a747e4fSDavid du Colombier 		if(b = a&0xf0000000){	/* assign = */
72*9a747e4fSDavid du Colombier 			a ^= b >> 24;
73*9a747e4fSDavid du Colombier 			a ^= b;
74*9a747e4fSDavid du Colombier 		}
75*9a747e4fSDavid du Colombier 	}
76*9a747e4fSDavid du Colombier 	return a;
77*9a747e4fSDavid du Colombier }
78*9a747e4fSDavid du Colombier 
79*9a747e4fSDavid du Colombier #define STRSIZE	1000
80*9a747e4fSDavid du Colombier 
81*9a747e4fSDavid du Colombier static Strnode *
nalloc(int n)82*9a747e4fSDavid du Colombier nalloc(int n)	/* get permanent storage for Strnode */
83*9a747e4fSDavid du Colombier {
84*9a747e4fSDavid du Colombier 	static char *curstp;
85*9a747e4fSDavid du Colombier 	static int nchleft;
86*9a747e4fSDavid du Colombier 	int k;
87*9a747e4fSDavid du Colombier 	char *p;
88*9a747e4fSDavid du Colombier 
89*9a747e4fSDavid du Colombier 	if(n < 4)
90*9a747e4fSDavid du Colombier 		n = 4;
91*9a747e4fSDavid du Colombier 	else if(k = n&3)	/* assign = */
92*9a747e4fSDavid du Colombier 		n += 4-k;
93*9a747e4fSDavid du Colombier 	n += sizeof(Strnode)-4;
94*9a747e4fSDavid du Colombier 	if(n > nchleft){
95*9a747e4fSDavid du Colombier 		nchleft = STRSIZE;
96*9a747e4fSDavid du Colombier 		while(nchleft < n)
97*9a747e4fSDavid du Colombier 			nchleft *= 2;
98*9a747e4fSDavid du Colombier 		if((curstp = malloc(nchleft)) == 0)
99*9a747e4fSDavid du Colombier 			panic("malloc(%d) failed in nalloc\n", nchleft);
100*9a747e4fSDavid du Colombier 	}
101*9a747e4fSDavid du Colombier 	p = curstp;
102*9a747e4fSDavid du Colombier 	curstp += n;
103*9a747e4fSDavid du Colombier 	nchleft -= n;
104*9a747e4fSDavid du Colombier 	return (Strnode*)p;
105*9a747e4fSDavid du Colombier }
106