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

# User Rev Content
1 greg 1.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     }