xref: /plan9/sys/src/cmd/replica/util.c (revision 3ff48bf5ed603850fcd251ddf13025d23d693782)
1 #include "all.h"
2 
3 void*
erealloc(void * a,int n)4 erealloc(void *a, int n)
5 {
6 	a = realloc(a, n);
7 	if(a==nil)
8 		sysfatal("realloc: %r");
9 	return a;
10 }
11 
12 char*
estrdup(char * s)13 estrdup(char *s)
14 {
15 	s = strdup(s);
16 	if(s == nil)
17 		sysfatal("strdup: %r");
18 	return s;
19 }
20 
21 void*
emalloc(int n)22 emalloc(int n)
23 {
24 	void *a;
25 
26 	a = mallocz(n, 1);
27 	if(a == nil)
28 		sysfatal("malloc: %r");
29 	return a;
30 }
31 
32 /*
33  *	Custom allocators to avoid malloc overheads on small objects.
34  * 	We never free these.  (See below.)
35  */
36 typedef struct Stringtab	Stringtab;
37 struct Stringtab {
38 	Stringtab *link;
39 	char *str;
40 };
41 static Stringtab*
taballoc(void)42 taballoc(void)
43 {
44 	static Stringtab *t;
45 	static uint nt;
46 
47 	if(nt == 0){
48 		t = malloc(64*sizeof(Stringtab));
49 		if(t == 0)
50 			sysfatal("out of memory");
51 		nt = 64;
52 	}
53 	nt--;
54 	return t++;
55 }
56 
57 static char*
xstrdup(char * s)58 xstrdup(char *s)
59 {
60 	char *r;
61 	int len;
62 	static char *t;
63 	static int nt;
64 
65 	len = strlen(s)+1;
66 	if(len >= 8192)
67 		sysfatal("strdup big string");
68 
69 	if(nt < len){
70 		t = malloc(8192);
71 		if(t == 0)
72 			sysfatal("out of memory");
73 		nt = 8192;
74 	}
75 	r = t;
76 	t += len;
77 	nt -= len;
78 	strcpy(r, s);
79 	return r;
80 }
81 
82 /*
83  *	Return a uniquely allocated copy of a string.
84  *	Don't free these -- they stay in the table for the
85  *	next caller who wants that particular string.
86  *	String comparison can be done with pointer comparison
87  *	if you know both strings are atoms.
88  */
89 static Stringtab *stab[1024];
90 
91 static uint
hash(char * s)92 hash(char *s)
93 {
94 	uint h;
95 	uchar *p;
96 
97 	h = 0;
98 	for(p=(uchar*)s; *p; p++)
99 		h = h*37 + *p;
100 	return h;
101 }
102 
103 char*
atom(char * str)104 atom(char *str)
105 {
106 	uint h;
107 	Stringtab *tab;
108 
109 	h = hash(str) % nelem(stab);
110 	for(tab=stab[h]; tab; tab=tab->link)
111 		if(strcmp(str, tab->str) == 0)
112 			return tab->str;
113 
114 	tab = taballoc();
115 	tab->str = xstrdup(str);
116 	tab->link = stab[h];
117 	stab[h] = tab;
118 	return tab->str;
119 }
120 
121 char*
unroot(char * path,char * root)122 unroot(char *path, char *root)
123 {
124 	int len;
125 	char *s;
126 
127 	len = strlen(root);
128 	while(len >= 1 && root[len-1]=='/')
129 		len--;
130 	if(strncmp(path, root, len)==0 && (path[len]=='/' || path[len]=='\0')){
131 		s = path+len;
132 		while(*s == '/')
133 			s++;
134 		return s;
135 	}
136 	return path;
137 }
138