home *** CD-ROM | disk | FTP | other *** search
- /* 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);
- }
-