home *** CD-ROM | disk | FTP | other *** search
- /* Copyright 1988 Regents of the University of California */
-
- #ifndef lint
- static char SCCSid[] = "@(#)savestr.c 2.2 7/3/92 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
- */
-
- #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];
-
- static int shash();
-
- extern char *savestr(), *strcpy(), *malloc();
-
- #define NULL 0
-
- #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) {
- eputs("Out of memory in savestr\n");
- quit(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;
- }
- }
-
-
- static int
- shash(s) /* hash a string */
- register char *s;
- {
- register int h = 0;
-
- while (*s)
- h += *s++;
-
- return(h % NHASH);
- }
-