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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.5 static const char RCSid[] = "$Id$";
3 greg 1.1 #endif
4 greg 1.2 /*
5 greg 1.1 * 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 greg 2.5 * reliably using their pointer values.
13 greg 1.1 * 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 greg 2.5 * External symbols declared in standard.h
19     */
20    
21 greg 2.6 #include "copyright.h"
22 greg 1.1
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 greg 2.3 #define hash(s) (shash(s)%NHASH)
35 greg 1.3
36 greg 1.1 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 greg 2.5 #define sfree(sp) free((void *)(sp))
45 greg 1.1
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 greg 2.3 hval = hash(str);
57 greg 1.1 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 greg 2.5 void
75 greg 1.1 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 greg 2.3 hval = hash(s);
84 greg 1.1 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 greg 2.3 int
99     shash(s)
100 greg 1.1 register char *s;
101     {
102     register int h = 0;
103    
104     while (*s)
105 greg 2.4 h = (h<<1 & 0x7fff) ^ (*s++ & 0xff);
106 greg 2.3 return(h);
107 greg 1.1 }