xref: /plan9/sys/src/cmd/replica/util.c (revision 3ff48bf5ed603850fcd251ddf13025d23d693782)
19a747e4fSDavid du Colombier #include "all.h"
29a747e4fSDavid du Colombier 
39a747e4fSDavid du Colombier void*
erealloc(void * a,int n)49a747e4fSDavid du Colombier erealloc(void *a, int n)
59a747e4fSDavid du Colombier {
69a747e4fSDavid du Colombier 	a = realloc(a, n);
79a747e4fSDavid du Colombier 	if(a==nil)
89a747e4fSDavid du Colombier 		sysfatal("realloc: %r");
99a747e4fSDavid du Colombier 	return a;
109a747e4fSDavid du Colombier }
119a747e4fSDavid du Colombier 
129a747e4fSDavid du Colombier char*
estrdup(char * s)139a747e4fSDavid du Colombier estrdup(char *s)
149a747e4fSDavid du Colombier {
159a747e4fSDavid du Colombier 	s = strdup(s);
169a747e4fSDavid du Colombier 	if(s == nil)
179a747e4fSDavid du Colombier 		sysfatal("strdup: %r");
189a747e4fSDavid du Colombier 	return s;
199a747e4fSDavid du Colombier }
209a747e4fSDavid du Colombier 
219a747e4fSDavid du Colombier void*
emalloc(int n)229a747e4fSDavid du Colombier emalloc(int n)
239a747e4fSDavid du Colombier {
249a747e4fSDavid du Colombier 	void *a;
259a747e4fSDavid du Colombier 
269a747e4fSDavid du Colombier 	a = mallocz(n, 1);
279a747e4fSDavid du Colombier 	if(a == nil)
289a747e4fSDavid du Colombier 		sysfatal("malloc: %r");
299a747e4fSDavid du Colombier 	return a;
309a747e4fSDavid du Colombier }
319a747e4fSDavid du Colombier 
329a747e4fSDavid du Colombier /*
339a747e4fSDavid du Colombier  *	Custom allocators to avoid malloc overheads on small objects.
349a747e4fSDavid du Colombier  * 	We never free these.  (See below.)
359a747e4fSDavid du Colombier  */
369a747e4fSDavid du Colombier typedef struct Stringtab	Stringtab;
379a747e4fSDavid du Colombier struct Stringtab {
389a747e4fSDavid du Colombier 	Stringtab *link;
399a747e4fSDavid du Colombier 	char *str;
409a747e4fSDavid du Colombier };
419a747e4fSDavid du Colombier static Stringtab*
taballoc(void)429a747e4fSDavid du Colombier taballoc(void)
439a747e4fSDavid du Colombier {
449a747e4fSDavid du Colombier 	static Stringtab *t;
459a747e4fSDavid du Colombier 	static uint nt;
469a747e4fSDavid du Colombier 
479a747e4fSDavid du Colombier 	if(nt == 0){
489a747e4fSDavid du Colombier 		t = malloc(64*sizeof(Stringtab));
499a747e4fSDavid du Colombier 		if(t == 0)
509a747e4fSDavid du Colombier 			sysfatal("out of memory");
519a747e4fSDavid du Colombier 		nt = 64;
529a747e4fSDavid du Colombier 	}
539a747e4fSDavid du Colombier 	nt--;
549a747e4fSDavid du Colombier 	return t++;
559a747e4fSDavid du Colombier }
569a747e4fSDavid du Colombier 
579a747e4fSDavid du Colombier static char*
xstrdup(char * s)589a747e4fSDavid du Colombier xstrdup(char *s)
599a747e4fSDavid du Colombier {
609a747e4fSDavid du Colombier 	char *r;
619a747e4fSDavid du Colombier 	int len;
629a747e4fSDavid du Colombier 	static char *t;
639a747e4fSDavid du Colombier 	static int nt;
649a747e4fSDavid du Colombier 
659a747e4fSDavid du Colombier 	len = strlen(s)+1;
669a747e4fSDavid du Colombier 	if(len >= 8192)
679a747e4fSDavid du Colombier 		sysfatal("strdup big string");
689a747e4fSDavid du Colombier 
699a747e4fSDavid du Colombier 	if(nt < len){
709a747e4fSDavid du Colombier 		t = malloc(8192);
719a747e4fSDavid du Colombier 		if(t == 0)
729a747e4fSDavid du Colombier 			sysfatal("out of memory");
739a747e4fSDavid du Colombier 		nt = 8192;
749a747e4fSDavid du Colombier 	}
759a747e4fSDavid du Colombier 	r = t;
769a747e4fSDavid du Colombier 	t += len;
779a747e4fSDavid du Colombier 	nt -= len;
789a747e4fSDavid du Colombier 	strcpy(r, s);
799a747e4fSDavid du Colombier 	return r;
809a747e4fSDavid du Colombier }
819a747e4fSDavid du Colombier 
829a747e4fSDavid du Colombier /*
839a747e4fSDavid du Colombier  *	Return a uniquely allocated copy of a string.
849a747e4fSDavid du Colombier  *	Don't free these -- they stay in the table for the
859a747e4fSDavid du Colombier  *	next caller who wants that particular string.
869a747e4fSDavid du Colombier  *	String comparison can be done with pointer comparison
879a747e4fSDavid du Colombier  *	if you know both strings are atoms.
889a747e4fSDavid du Colombier  */
899a747e4fSDavid du Colombier static Stringtab *stab[1024];
909a747e4fSDavid du Colombier 
919a747e4fSDavid du Colombier static uint
hash(char * s)929a747e4fSDavid du Colombier hash(char *s)
939a747e4fSDavid du Colombier {
949a747e4fSDavid du Colombier 	uint h;
959a747e4fSDavid du Colombier 	uchar *p;
969a747e4fSDavid du Colombier 
979a747e4fSDavid du Colombier 	h = 0;
989a747e4fSDavid du Colombier 	for(p=(uchar*)s; *p; p++)
999a747e4fSDavid du Colombier 		h = h*37 + *p;
1009a747e4fSDavid du Colombier 	return h;
1019a747e4fSDavid du Colombier }
1029a747e4fSDavid du Colombier 
1039a747e4fSDavid du Colombier char*
atom(char * str)1049a747e4fSDavid du Colombier atom(char *str)
1059a747e4fSDavid du Colombier {
1069a747e4fSDavid du Colombier 	uint h;
1079a747e4fSDavid du Colombier 	Stringtab *tab;
1089a747e4fSDavid du Colombier 
1099a747e4fSDavid du Colombier 	h = hash(str) % nelem(stab);
1109a747e4fSDavid du Colombier 	for(tab=stab[h]; tab; tab=tab->link)
1119a747e4fSDavid du Colombier 		if(strcmp(str, tab->str) == 0)
1129a747e4fSDavid du Colombier 			return tab->str;
1139a747e4fSDavid du Colombier 
1149a747e4fSDavid du Colombier 	tab = taballoc();
1159a747e4fSDavid du Colombier 	tab->str = xstrdup(str);
1169a747e4fSDavid du Colombier 	tab->link = stab[h];
1179a747e4fSDavid du Colombier 	stab[h] = tab;
1189a747e4fSDavid du Colombier 	return tab->str;
1199a747e4fSDavid du Colombier }
1209a747e4fSDavid du Colombier 
1219a747e4fSDavid du Colombier char*
unroot(char * path,char * root)1229a747e4fSDavid du Colombier unroot(char *path, char *root)
1239a747e4fSDavid du Colombier {
1249a747e4fSDavid du Colombier 	int len;
1259a747e4fSDavid du Colombier 	char *s;
1269a747e4fSDavid du Colombier 
1279a747e4fSDavid du Colombier 	len = strlen(root);
128*3ff48bf5SDavid du Colombier 	while(len >= 1 && root[len-1]=='/')
1295d459b5aSDavid du Colombier 		len--;
1305d459b5aSDavid du Colombier 	if(strncmp(path, root, len)==0 && (path[len]=='/' || path[len]=='\0')){
1319a747e4fSDavid du Colombier 		s = path+len;
1325d459b5aSDavid du Colombier 		while(*s == '/')
1335d459b5aSDavid du Colombier 			s++;
134*3ff48bf5SDavid du Colombier 		return s;
1359a747e4fSDavid du Colombier 	}
1369a747e4fSDavid du Colombier 	return path;
1379a747e4fSDavid du Colombier }
138