ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 2.6
Committed: Tue Feb 25 02:47:22 2003 UTC (21 years, 2 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.5: +1 -56 lines
Log Message:
Replaced inline copyright notice with #include "copyright.h"

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id$";
3 #endif
4 /*
5 * savestr.c - routines for efficient string storage.
6 *
7 * Savestr(s) stores a shared read-only string.
8 * Freestr(s) indicates a client is finished with a string.
9 * All strings must be null-terminated. There is
10 * no imposed length limit.
11 * Strings stored with savestr(s) can be equated
12 * reliably using their pointer values.
13 * Calls to savestr(s) and freestr(s) should be
14 * balanced (obviously). The last call to freestr(s)
15 * frees memory associated with the string; it should
16 * never be referenced again.
17 *
18 * External symbols declared in standard.h
19 */
20
21 #include "copyright.h"
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 #define hash(s) (shash(s)%NHASH)
35
36 extern char *savestr(), *strcpy(), *malloc();
37
38 #define NULL 0
39
40 #define string(sp) ((char *)((sp)+1))
41
42 #define salloc(str) (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
43
44 #define sfree(sp) free((void *)(sp))
45
46
47 char *
48 savestr(str) /* save a string */
49 char *str;
50 {
51 register int hval;
52 register S_HEAD *sp;
53
54 if (str == NULL)
55 return(NULL);
56 hval = hash(str);
57 for (sp = stab[hval]; sp != NULL; sp = sp->next)
58 if (!strcmp(str, string(sp))) {
59 sp->nl++;
60 return(string(sp));
61 }
62 if ((sp = salloc(str)) == NULL) {
63 eputs("Out of memory in savestr\n");
64 quit(1);
65 }
66 strcpy(string(sp), str);
67 sp->nl = 1;
68 sp->next = stab[hval];
69 stab[hval] = sp;
70 return(string(sp));
71 }
72
73
74 void
75 freestr(s) /* free a string */
76 char *s;
77 {
78 int hval;
79 register S_HEAD *spl, *sp;
80
81 if (s == NULL)
82 return;
83 hval = hash(s);
84 for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
85 if (s == string(sp)) {
86 if (--sp->nl > 0)
87 return;
88 if (spl != NULL)
89 spl->next = sp->next;
90 else
91 stab[hval] = sp->next;
92 sfree(sp);
93 return;
94 }
95 }
96
97
98 int
99 shash(s)
100 register char *s;
101 {
102 register int h = 0;
103
104 while (*s)
105 h = (h<<1 & 0x7fff) ^ (*s++ & 0xff);
106 return(h);
107 }