ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 2.9
Committed: Fri Nov 14 17:22:06 2003 UTC (20 years, 5 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.8: +6 -7 lines
Log Message:
Reduced compile warnings, and other compatibility fixes.

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.9 static const char RCSid[] = "$Id: savestr.c,v 2.8 2003/10/27 10:19:31 schorsch Exp $";
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 schorsch 2.7 #include <string.h>
24     #include <stdlib.h>
25    
26 schorsch 2.8 #include "rtmisc.h"
27 schorsch 2.9 #include "rterror.h"
28     #include "rtio.h"
29 schorsch 2.7
30 greg 1.1 #ifndef NHASH
31     #define NHASH 509 /* hash table size (prime!) */
32     #endif
33    
34     typedef struct s_head {
35     struct s_head *next; /* next in hash list */
36     int nl; /* links count */
37     } S_HEAD; /* followed by the string itself */
38    
39     static S_HEAD *stab[NHASH];
40    
41 greg 2.3 #define hash(s) (shash(s)%NHASH)
42 greg 1.1
43     #define string(sp) ((char *)((sp)+1))
44    
45     #define salloc(str) (S_HEAD *)malloc(sizeof(S_HEAD)+1+strlen(str))
46    
47 greg 2.5 #define sfree(sp) free((void *)(sp))
48 greg 1.1
49    
50     char *
51 schorsch 2.9 savestr(char *str) /* save a string */
52 greg 1.1 {
53     register int hval;
54     register S_HEAD *sp;
55    
56     if (str == NULL)
57     return(NULL);
58 greg 2.3 hval = hash(str);
59 greg 1.1 for (sp = stab[hval]; sp != NULL; sp = sp->next)
60     if (!strcmp(str, string(sp))) {
61     sp->nl++;
62     return(string(sp));
63     }
64     if ((sp = salloc(str)) == NULL) {
65     eputs("Out of memory in savestr\n");
66     quit(1);
67     }
68     strcpy(string(sp), str);
69     sp->nl = 1;
70     sp->next = stab[hval];
71     stab[hval] = sp;
72     return(string(sp));
73     }
74    
75    
76 greg 2.5 void
77 schorsch 2.9 freestr(char *s) /* free a string */
78 greg 1.1 {
79     int hval;
80     register S_HEAD *spl, *sp;
81    
82     if (s == NULL)
83     return;
84 greg 2.3 hval = hash(s);
85 greg 1.1 for (spl = NULL, sp = stab[hval]; sp != NULL; spl = sp, sp = sp->next)
86     if (s == string(sp)) {
87     if (--sp->nl > 0)
88     return;
89     if (spl != NULL)
90     spl->next = sp->next;
91     else
92     stab[hval] = sp->next;
93     sfree(sp);
94     return;
95     }
96     }
97    
98    
99 greg 2.3 int
100 schorsch 2.9 shash(register char *s)
101 greg 1.1 {
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 }