home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Encyclopedia of Graphics File Formats Companion
/
GFF_CD.ISO
/
formats
/
ttddd
/
spec
/
t3d_doc
/
igensurf.zoo
/
src
/
savestr.c
< prev
Wrap
C/C++ Source or Header
|
1991-09-25
|
2KB
|
123 lines
/* Copyright 1988 Regents of the University of California */
#ifndef lint
static char SCCSid[] = "@(#)savestr.c 1.2 2/2/89 LBL";
#endif
/*
* savestr.c - routines for efficient string storage.
*
* Savestr(s) stores a shared read-only string.
* Freestr(s) indicates a client is finished with a string.
* All strings must be null-terminated. There is
* no imposed length limit.
* Strings stored with savestr(s) can be equated
* reliably using their pointer values. A tailored version
* of strcmp(s1,s2) is included.
* Calls to savestr(s) and freestr(s) should be
* balanced (obviously). The last call to freestr(s)
* frees memory associated with the string; it should
* never be referenced again.
*
* 5/14/87
*/
#include <stdio.h>
#ifndef NHASH
#define NHASH 509 /* hash table size (prime!) */
#endif
typedef struct s_head {
struct s_head *next; /* next in hash list */
int nl; /* links count */
} S_HEAD; /* followed by the string itself */
static S_HEAD *stab[NHASH];
extern char *savestr(), *strcpy(), *malloc();
#define string(sp) ((char *)((sp)+1))
#define salloc(str) (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
#define sfree(sp) free((char *)(sp))
char *
savestr(str) /* save a string */
char *str;
{
register int hval;
register S_HEAD *sp;
if (str == NULL)
return(NULL);
hval = shash(str);
for (sp = stab[hval]; sp != NULL; sp = sp->next)
if (!strcmp(str, string(sp))) {
sp->nl++;
return(string(sp));
}
if ((sp = salloc(str)) == NULL) {
fprintf(stderr, "Out of memory in savestr\n");
exit(1);
}
strcpy(string(sp), str);
sp->nl = 1;
sp->next = stab[hval];
stab[hval] = sp;
return(string(sp));
}
freestr(s) /* free a string */
char *s;
{
int hval;
register S_HEAD *spl, *sp;
if (s == NULL)
return;
hval = shash(s);
for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
if (s == string(sp)) {
if (--sp->nl > 0)
return;
if (spl != NULL)
spl->next = sp->next;
else
stab[hval] = sp->next;
sfree(sp);
return;
}
}
int
strcmp(s1, s2) /* check for s1==s2 */
register char *s1, *s2;
{
if (s1 == s2)
return(0);
while (*s1 == *s2++)
if (!*s1++)
return(0);
return(*s1 - *--s2);
}
static int
shash(s) /* hash a string */
register char *s;
{
register int h = 0;
while (*s)
h += *s++;
return(h % NHASH);
}