ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/savestr.c
Revision: 1.3
Committed: Mon Oct 28 09:47:27 1991 UTC (32 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 1.2: +2 -0 lines
Log Message:
compatibility fixes for SGI libraries

File Contents

# Content
1 /* Copyright 1988 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * savestr.c - routines for efficient string storage.
9 *
10 * Savestr(s) stores a shared read-only string.
11 * Freestr(s) indicates a client is finished with a string.
12 * All strings must be null-terminated. There is
13 * no imposed length limit.
14 * Strings stored with savestr(s) can be equated
15 * reliably using their pointer values. A tailored version
16 * of strcmp(s1,s2) is included.
17 * Calls to savestr(s) and freestr(s) should be
18 * balanced (obviously). The last call to freestr(s)
19 * frees memory associated with the string; it should
20 * never be referenced again.
21 *
22 * 5/14/87
23 */
24
25 #ifndef NHASH
26 #define NHASH 509 /* hash table size (prime!) */
27 #endif
28
29 typedef struct s_head {
30 struct s_head *next; /* next in hash list */
31 int nl; /* links count */
32 } S_HEAD; /* followed by the string itself */
33
34 static S_HEAD *stab[NHASH];
35
36 static int shash();
37
38 extern char *savestr(), *strcpy(), *malloc();
39
40 #define NULL 0
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((char *)(sp))
47
48
49 char *
50 savestr(str) /* save a string */
51 char *str;
52 {
53 register int hval;
54 register S_HEAD *sp;
55
56 if (str == NULL)
57 return(NULL);
58 hval = shash(str);
59 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 freestr(s) /* free a string */
77 char *s;
78 {
79 int hval;
80 register S_HEAD *spl, *sp;
81
82 if (s == NULL)
83 return;
84 hval = shash(s);
85 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 int
100 strcmp(s1, s2) /* check for s1==s2 */
101 register char *s1, *s2;
102 {
103 if (s1 == s2)
104 return(0);
105
106 while (*s1 == *s2++)
107 if (!*s1++)
108 return(0);
109
110 return(*s1 - *--s2);
111 }
112
113
114 static int
115 shash(s) /* hash a string */
116 register char *s;
117 {
118 register int h = 0;
119
120 while (*s)
121 h += *s++;
122
123 return(h % NHASH);
124 }