ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 1.1
Committed: Thu Feb 2 10:34:40 1989 UTC (35 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
Log Message:
Initial revision

File Contents

# Content
1 /*
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6 * savestr.c - routines for efficient string storage.
7 *
8 * Savestr(s) stores a shared read-only string.
9 * Freestr(s) indicates a client is finished with a string.
10 * All strings must be null-terminated. There is
11 * no imposed length limit.
12 * Strings stored with savestr(s) can be equated
13 * reliably using their pointer values. A tailored version
14 * of strcmp(s1,s2) is included.
15 * Calls to savestr(s) and freestr(s) should be
16 * balanced (obviously). The last call to freestr(s)
17 * frees memory associated with the string; it should
18 * never be referenced again.
19 *
20 * 5/14/87
21 */
22
23 #ifndef NHASH
24 #define NHASH 509 /* hash table size (prime!) */
25 #endif
26
27 typedef struct s_head {
28 struct s_head *next; /* next in hash list */
29 int nl; /* links count */
30 } S_HEAD; /* followed by the string itself */
31
32 static S_HEAD *stab[NHASH];
33
34 extern char *savestr(), *strcpy(), *malloc();
35
36 #define NULL 0
37
38 #define string(sp) ((char *)((sp)+1))
39
40 #define salloc(str) (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
41
42 #define sfree(sp) free((char *)(sp))
43
44
45 char *
46 savestr(str) /* save a string */
47 char *str;
48 {
49 register int hval;
50 register S_HEAD *sp;
51
52 if (str == NULL)
53 return(NULL);
54 hval = shash(str);
55 for (sp = stab[hval]; sp != NULL; sp = sp->next)
56 if (!strcmp(str, string(sp))) {
57 sp->nl++;
58 return(string(sp));
59 }
60 if ((sp = salloc(str)) == NULL) {
61 eputs("Out of memory in savestr\n");
62 quit(1);
63 }
64 strcpy(string(sp), str);
65 sp->nl = 1;
66 sp->next = stab[hval];
67 stab[hval] = sp;
68 return(string(sp));
69 }
70
71
72 freestr(s) /* free a string */
73 char *s;
74 {
75 int hval;
76 register S_HEAD *spl, *sp;
77
78 if (s == NULL)
79 return;
80 hval = shash(s);
81 for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
82 if (s == string(sp)) {
83 if (--sp->nl > 0)
84 return;
85 if (spl != NULL)
86 spl->next = sp->next;
87 else
88 stab[hval] = sp->next;
89 sfree(sp);
90 return;
91 }
92 }
93
94
95 int
96 strcmp(s1, s2) /* check for s1==s2 */
97 register char *s1, *s2;
98 {
99 if (s1 == s2)
100 return(0);
101
102 while (*s1 == *s2++)
103 if (!*s1++)
104 return(0);
105
106 return(*s1 - *--s2);
107 }
108
109
110 static int
111 shash(s) /* hash a string */
112 register char *s;
113 {
114 register int h = 0;
115
116 while (*s)
117 h += *s++;
118
119 return(h % NHASH);
120 }