#include "all.h" void*erealloc(void *a, int n){ a = realloc(a, n); if(a==nil) sysfatal("realloc: %r"); return a;} char*estrdup(char *s){ s = strdup(s); if(s == nil) sysfatal("strdup: %r"); return s;} void*emalloc(int n){ void *a; a = mallocz(n, 1); if(a == nil) sysfatal("malloc: %r"); return a;} /* * Custom allocators to avoid malloc overheads on small objects. * We never free these. (See below.) */typedef struct Stringtab Stringtab;struct Stringtab { Stringtab *link; char *str;};static Stringtab*taballoc(void){ static Stringtab *t; static uint nt; if(nt == 0){ t = malloc(64*sizeof(Stringtab)); if(t == 0) sysfatal("out of memory"); nt = 64; } nt--; return t++;} static char*xstrdup(char *s){ char *r; int len; static char *t; static int nt; len = strlen(s)+1; if(len >= 8192) sysfatal("strdup big string"); if(nt < len){ t = malloc(8192); if(t == 0) sysfatal("out of memory"); nt = 8192; } r = t; t += len; nt -= len; strcpy(r, s); return r;} /* * Return a uniquely allocated copy of a string. * Don't free these -- they stay in the table for the * next caller who wants that particular string. * String comparison can be done with pointer comparison * if you know both strings are atoms. */static Stringtab *stab[1024]; static uinthash(char *s){ uint h; uchar *p; h = 0; for(p=(uchar*)s; *p; p++) h = h*37 + *p; return h;} char*atom(char *str){ uint h; Stringtab *tab; h = hash(str) % nelem(stab); for(tab=stab[h]; tab; tab=tab->link) if(strcmp(str, tab->str) == 0) return tab->str; tab = taballoc(); tab->str = xstrdup(str); tab->link = stab[h]; stab[h] = tab; return tab->str;} char*unroot(char *path, char *root){ int len; char *s; len = strlen(root); while(len >= 1 && root[len-1]=='/') len--; if(strncmp(path, root, len)==0 && (path[len]=='/' || path[len]=='\0')){ s = path+len; while(*s == '/') s++; return s; } return path;}
#include "all.h"
void*
erealloc(void *a, int n)
{
a = realloc(a, n);
if(a==nil)
sysfatal("realloc: %r");
return a;
}
char*
estrdup(char *s)
{
s = strdup(s);
if(s == nil)
sysfatal("strdup: %r");
return s;
}
void*
emalloc(int n)
{
void *a;
a = mallocz(n, 1);
if(a == nil)
sysfatal("malloc: %r");
return a;
}
/*
* Custom allocators to avoid malloc overheads on small objects.
* We never free these. (See below.)
*/
typedef struct Stringtab Stringtab;
struct Stringtab {
Stringtab *link;
char *str;
};
static Stringtab*
taballoc(void)
{
static Stringtab *t;
static uint nt;
if(nt == 0){
t = malloc(64*sizeof(Stringtab));
if(t == 0)
sysfatal("out of memory");
nt = 64;
}
nt--;
return t++;
}
static char*
xstrdup(char *s)
{
char *r;
int len;
static char *t;
static int nt;
len = strlen(s)+1;
if(len >= 8192)
sysfatal("strdup big string");
if(nt < len){
t = malloc(8192);
if(t == 0)
sysfatal("out of memory");
nt = 8192;
}
r = t;
t += len;
nt -= len;
strcpy(r, s);
return r;
}
/*
* Return a uniquely allocated copy of a string.
* Don't free these -- they stay in the table for the
* next caller who wants that particular string.
* String comparison can be done with pointer comparison
* if you know both strings are atoms.
*/
static Stringtab *stab[1024];
static uint
hash(char *s)
{
uint h;
uchar *p;
h = 0;
for(p=(uchar*)s; *p; p++)
h = h*37 + *p;
return h;
}
char*
atom(char *str)
{
uint h;
Stringtab *tab;
h = hash(str) % nelem(stab);
for(tab=stab[h]; tab; tab=tab->link)
if(strcmp(str, tab->str) == 0)
return tab->str;
tab = taballoc();
tab->str = xstrdup(str);
tab->link = stab[h];
stab[h] = tab;
return tab->str;
}
char*
unroot(char *path, char *root)
{
int len;
char *s;
len = strlen(root);
while(len >= 1 && root[len-1]=='/')
len--;
if(strncmp(path, root, len)==0 && (path[len]=='/' || path[len]=='\0')){
s = path+len;
while(*s == '/')
s++;
return s;
}
return path;
}