ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 2.12
Committed: Sat Dec 28 18:05:14 2019 UTC (4 years, 4 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R3
Changes since 2.11: +1 -2 lines
Log Message:
Removed redundant include files

File Contents

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