]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/replica/util.c
ndb/dnsquery, ndb/csquery: handle long lines
[plan9front.git] / sys / src / cmd / replica / util.c
1 #include "all.h"
2
3 void*
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*
13 estrdup(char *s)
14 {
15         s = strdup(s);
16         if(s == nil)
17                 sysfatal("strdup: %r");
18         return s;
19 }
20
21 void*
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*
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*
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
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*
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*
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 }