ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/modobject.c
Revision: 2.20
Committed: Mon Feb 1 17:36:45 2021 UTC (3 years, 3 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.19: +5 -4 lines
Log Message:
fix: prophylactic against 64-bit architectures with 32-bit int's

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: modobject.c,v 2.19 2020/10/17 17:48:46 greg Exp $";
3 #endif
4 /*
5 * Routines for tracking object modifiers
6 *
7 * External symbols declared in object.h
8 */
9
10 #include "copyright.h"
11
12 #include "standard.h"
13
14 #include "object.h"
15
16 #include "otypes.h"
17
18
19 static struct ohtab {
20 int hsiz; /* current table size */
21 OBJECT *htab; /* table, if allocated */
22 } modtab = {100, NULL}, objtab = {1000, NULL}; /* modifiers and objects */
23
24 static int otndx(char *, struct ohtab *);
25
26
27 OBJECT
28 objndx( /* get object number from pointer */
29 OBJREC *op
30 )
31 {
32 int i;
33 long j;
34
35 for (i = (nobjects-1)>>OBJBLKSHFT; i >= 0; i--) {
36 j = op - objblock[i];
37 if ((j >= 0) & (j < OBJBLKSIZ))
38 return(((OBJECT)i<<OBJBLKSHFT) + (OBJECT)j);
39 }
40 return(OVOID);
41 }
42
43
44 OBJECT
45 lastmod( /* find modifier definition before obj */
46 OBJECT obj,
47 char *mname
48 )
49 {
50 OBJREC *op;
51 int i;
52
53 i = modifier(mname); /* try hash table first */
54 if ((obj == OVOID) | (i < obj))
55 return(i);
56 for (i = obj; i-- > 0; ) { /* need to search */
57 op = objptr(i);
58 if (ismodifier(op->otype) && op->oname[0] == mname[0] &&
59 !strcmp(op->oname, mname))
60 return(i);
61 }
62 return(OVOID);
63 }
64
65
66 OBJECT
67 modifier( /* get a modifier number from its name */
68 char *mname
69 )
70 {
71 int ndx;
72
73 ndx = otndx(mname, &modtab);
74 return(modtab.htab[ndx]);
75 }
76
77
78 #ifdef GETOBJ
79 OBJECT
80 object( /* get an object number from its name */
81 char *oname
82 )
83 {
84 int ndx;
85
86 ndx = otndx(oname, &objtab);
87 return(objtab.htab[ndx]);
88 }
89 #endif
90
91
92 int
93 eqreal( /* are two real values close enough to equal? */
94 double d1,
95 double d2
96 )
97 {
98 if (d2 != 0.0)
99 d1 = d1/d2 - 1.0;
100 return((-FTINY <= d1) & (d1 <= FTINY));
101 }
102
103
104 int
105 eqobjects( /* check if two objects are equal */
106 OBJECT obj1,
107 OBJECT obj2
108 )
109 {
110 OBJREC *op1, *op2;
111 int i, n;
112
113 while (obj1 != obj2) {
114 if (obj1 == OVOID)
115 return(0);
116 if (obj2 == OVOID)
117 return(0);
118 op1 = objptr(obj1);
119 op2 = objptr(obj2);
120 if (op1->otype != op2->otype)
121 return(0);
122 if (op1->oargs.nsargs != op2->oargs.nsargs)
123 return(0);
124 if (op1->oargs.nfargs != op2->oargs.nfargs)
125 return(0);
126 #ifdef IARGS
127 if (op1->oargs.niargs != op2->oargs.niargs)
128 return(0);
129 for (i = op1->oargs.niargs; i-- > 0; )
130 if (op1->oargs.iarg[i] != op2->oargs.iarg[i])
131 return(0);
132 #endif
133 for (i = op1->oargs.nfargs; i-- > 0; )
134 if (!eqreal(op1->oargs.farg[i], op2->oargs.farg[i]))
135 return(0);
136 n = 0;
137 switch (op1->otype) { /* special cases (KEEP CONSISTENT!) */
138 case MOD_ALIAS:
139 case MAT_ILLUM:
140 case MAT_MIRROR:
141 n = (op1->oargs.nsargs > 0);
142 break;
143 case MIX_FUNC:
144 case MIX_DATA:
145 case MIX_TEXT:
146 case MIX_PICT:
147 n = 2*(op1->oargs.nsargs >= 2);
148 break;
149 case MAT_CLIP:
150 n = op1->oargs.nsargs;
151 break;
152 }
153 /* check other string arguments */
154 for (i = op1->oargs.nsargs; i-- > n; )
155 if (strcmp(op1->oargs.sarg[i], op2->oargs.sarg[i]))
156 return(0);
157 while (n-- > 0) /* check modifier references */
158 if (!eqobjects( lastmod(obj1, op1->oargs.sarg[n]),
159 lastmod(obj2, op2->oargs.sarg[n]) ))
160 return(0);
161 obj1 = op1->omod;
162 obj2 = op2->omod;
163 }
164 return(1);
165 }
166
167
168 void
169 insertobject( /* insert new object into our list */
170 OBJECT obj
171 )
172 {
173 int i;
174
175 if (ismodifier(objptr(obj)->otype)) {
176 i = otndx(objptr(obj)->oname, &modtab);
177 if (eqobjects(obj, modtab.htab[i]))
178 return; /* don't index if same as earlier def. */
179 modtab.htab[i] = obj;
180 }
181 #ifdef GETOBJ
182 else {
183 i = otndx(objptr(obj)->oname, &objtab);
184 objtab.htab[i] = obj;
185 }
186 #endif
187 for (i = 0; addobjnotify[i] != NULL; i++)
188 (*addobjnotify[i])(obj);
189 }
190
191
192 void
193 truncobjndx(void) /* remove bogus table entries past end */
194 {
195 int ndx;
196
197 if (nobjects <= 0) {
198 if (modtab.htab != NULL) {
199 free((void *)modtab.htab);
200 modtab.htab = NULL;
201 modtab.hsiz = 100;
202 }
203 if (objtab.htab != NULL) {
204 free((void *)objtab.htab);
205 objtab.htab = NULL;
206 objtab.hsiz = 100;
207 }
208 return;
209 }
210 for (ndx = modtab.hsiz*(modtab.htab != NULL); ndx--; )
211 if (modtab.htab[ndx] >= nobjects)
212 modtab.htab[ndx] = OVOID;
213
214 for (ndx = objtab.hsiz*(objtab.htab != NULL); ndx--; )
215 if (objtab.htab[ndx] >= nobjects)
216 objtab.htab[ndx] = OVOID;
217 }
218
219
220 static int
221 nexthsiz( /* return next hash table size */
222 int oldsiz
223 )
224 {
225 static int hsiztab[] = {
226 251, 509, 1021, 2039, 4093, 8191, 16381,
227 32749, 65521, 131071, 262139, 0
228 };
229 int *hsp;
230
231 for (hsp = hsiztab; *hsp; hsp++)
232 if (*hsp > oldsiz)
233 return(*hsp);
234 return(oldsiz*2 + 1); /* not always prime */
235 }
236
237
238 static int
239 otndx( /* get object table index for name */
240 char *name,
241 struct ohtab *tab
242 )
243 {
244 char *onm;
245 OBJECT *oldhtab;
246 int hval, i;
247 int ndx;
248
249 if (tab->htab == NULL) { /* new table */
250 tab->hsiz = nexthsiz(tab->hsiz);
251 tab->htab = (OBJECT *)malloc(tab->hsiz*sizeof(OBJECT));
252 if (tab->htab == NULL)
253 error(SYSTEM, "out of memory in otndx");
254 ndx = tab->hsiz;
255 while (ndx--) /* empty it */
256 tab->htab[ndx] = OVOID;
257 }
258 /* look up object */
259 hval = shash(name);
260 tryagain:
261 for (i = 0; i < tab->hsiz; i++) {
262 ndx = (hval + (unsigned long)i*i) % tab->hsiz;
263 if (tab->htab[ndx] == OVOID)
264 return(ndx);
265 onm = objptr(tab->htab[ndx])->oname;
266 if (onm != NULL && !strcmp(onm, name))
267 return(ndx);
268 }
269 /* table is full, reallocate */
270 oldhtab = tab->htab;
271 ndx = tab->hsiz;
272 tab->htab = NULL;
273 while (ndx--)
274 if (oldhtab[ndx] != OVOID) {
275 onm = objptr(oldhtab[ndx])->oname;
276 if (onm == NULL)
277 continue;
278 i = otndx(onm, tab);
279 tab->htab[i] = oldhtab[ndx];
280 }
281 free((void *)oldhtab);
282 goto tryagain; /* should happen only once! */
283 }