137 lines · 2.0 KB · C
RawDownload
#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;}