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