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

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.20 static const char RCSid[] = "$Id: modobject.c,v 2.19 2020/10/17 17:48:46 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * Routines for tracking object modifiers
6 greg 2.7 *
7     * External symbols declared in object.h
8     */
9    
10 greg 2.8 #include "copyright.h"
11 greg 1.1
12     #include "standard.h"
13    
14     #include "object.h"
15    
16 greg 1.2 #include "otypes.h"
17    
18 greg 1.1
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 schorsch 2.10 static int otndx(char *, struct ohtab *);
25 greg 1.3
26 greg 1.1
27 greg 2.9 OBJECT
28 greg 2.13 objndx( /* get object number from pointer */
29     OBJREC *op
30     )
31 greg 1.1 {
32 greg 2.20 int i;
33     long j;
34 greg 1.1
35 greg 2.20 for (i = (nobjects-1)>>OBJBLKSHFT; i >= 0; i--) {
36 greg 2.3 j = op - objblock[i];
37 greg 2.12 if ((j >= 0) & (j < OBJBLKSIZ))
38 greg 2.20 return(((OBJECT)i<<OBJBLKSHFT) + (OBJECT)j);
39 greg 2.3 }
40     return(OVOID);
41 greg 1.1 }
42    
43    
44 greg 2.9 OBJECT
45 greg 2.13 lastmod( /* find modifier definition before obj */
46     OBJECT obj,
47     char *mname
48     )
49 greg 2.3 {
50 greg 2.13 OBJREC *op;
51     int i;
52 greg 2.3
53 greg 2.4 i = modifier(mname); /* try hash table first */
54 greg 2.12 if ((obj == OVOID) | (i < obj))
55 greg 2.4 return(i);
56     for (i = obj; i-- > 0; ) { /* need to search */
57 greg 2.3 op = objptr(i);
58 greg 2.13 if (ismodifier(op->otype) && op->oname[0] == mname[0] &&
59     !strcmp(op->oname, mname))
60 greg 2.3 return(i);
61     }
62     return(OVOID);
63     }
64    
65    
66 greg 2.9 OBJECT
67 greg 2.13 modifier( /* get a modifier number from its name */
68     char *mname
69     )
70 greg 1.1 {
71 greg 2.13 int ndx;
72 greg 1.1
73     ndx = otndx(mname, &modtab);
74     return(modtab.htab[ndx]);
75     }
76    
77    
78 greg 2.3 #ifdef GETOBJ
79 greg 2.9 OBJECT
80 greg 2.13 object( /* get an object number from its name */
81     char *oname
82     )
83 greg 2.3 {
84 greg 2.13 int ndx;
85 greg 2.3
86     ndx = otndx(oname, &objtab);
87     return(objtab.htab[ndx]);
88     }
89     #endif
90    
91    
92 greg 2.15 int
93 greg 2.14 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 greg 2.17 int i, n;
112 greg 2.14
113 greg 2.15 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 greg 2.14 #ifdef IARGS
127 greg 2.15 if (op1->oargs.niargs != op2->oargs.niargs)
128 greg 2.14 return(0);
129 greg 2.15 for (i = op1->oargs.niargs; i-- > 0; )
130     if (op1->oargs.iarg[i] != op2->oargs.iarg[i])
131     return(0);
132 greg 2.14 #endif
133 greg 2.15 for (i = op1->oargs.nfargs; i-- > 0; )
134     if (!eqreal(op1->oargs.farg[i], op2->oargs.farg[i]))
135     return(0);
136 greg 2.17 n = 0;
137 greg 2.16 switch (op1->otype) { /* special cases (KEEP CONSISTENT!) */
138     case MOD_ALIAS:
139     case MAT_ILLUM:
140     case MAT_MIRROR:
141 greg 2.17 n = (op1->oargs.nsargs > 0);
142 greg 2.16 break;
143     case MIX_FUNC:
144     case MIX_DATA:
145     case MIX_TEXT:
146     case MIX_PICT:
147 greg 2.17 n = 2*(op1->oargs.nsargs >= 2);
148 greg 2.16 break;
149     case MAT_CLIP:
150 greg 2.17 n = op1->oargs.nsargs;
151 greg 2.16 break;
152     }
153 greg 2.17 /* 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 greg 2.16 return(0);
161 greg 2.15 obj1 = op1->omod;
162     obj2 = op2->omod;
163     }
164 greg 2.14 return(1);
165     }
166    
167    
168 greg 2.7 void
169 greg 2.13 insertobject( /* insert new object into our list */
170     OBJECT obj
171     )
172 greg 1.1 {
173 greg 2.13 int i;
174 greg 1.1
175     if (ismodifier(objptr(obj)->otype)) {
176     i = otndx(objptr(obj)->oname, &modtab);
177 greg 2.14 if (eqobjects(obj, modtab.htab[i]))
178 greg 2.16 return; /* don't index if same as earlier def. */
179 greg 1.1 modtab.htab[i] = obj;
180     }
181 greg 2.3 #ifdef GETOBJ
182     else {
183     i = otndx(objptr(obj)->oname, &objtab);
184     objtab.htab[i] = obj;
185     }
186     #endif
187 greg 1.1 for (i = 0; addobjnotify[i] != NULL; i++)
188     (*addobjnotify[i])(obj);
189     }
190    
191    
192 greg 2.7 void
193 greg 2.18 truncobjndx(void) /* remove bogus table entries past end */
194 greg 2.7 {
195 greg 2.18 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 greg 2.7 }
210 greg 2.18 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 greg 2.7 }
218    
219    
220 greg 1.1 static int
221 greg 2.13 nexthsiz( /* return next hash table size */
222     int oldsiz
223     )
224 greg 1.1 {
225     static int hsiztab[] = {
226 greg 2.19 251, 509, 1021, 2039, 4093, 8191, 16381,
227     32749, 65521, 131071, 262139, 0
228 greg 1.1 };
229 greg 2.13 int *hsp;
230 greg 1.1
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 greg 2.13 otndx( /* get object table index for name */
240     char *name,
241     struct ohtab *tab
242     )
243 greg 1.1 {
244 greg 2.19 char *onm;
245 greg 1.1 OBJECT *oldhtab;
246     int hval, i;
247 greg 2.13 int ndx;
248 greg 1.1
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 greg 2.11 ndx = (hval + (unsigned long)i*i) % tab->hsiz;
263 greg 2.19 if (tab->htab[ndx] == OVOID)
264     return(ndx);
265     onm = objptr(tab->htab[ndx])->oname;
266     if (onm != NULL && !strcmp(onm, name))
267 greg 1.1 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 greg 2.19 onm = objptr(oldhtab[ndx])->oname;
276     if (onm == NULL)
277     continue;
278     i = otndx(onm, tab);
279 greg 1.1 tab->htab[i] = oldhtab[ndx];
280     }
281 greg 2.7 free((void *)oldhtab);
282 greg 1.1 goto tryagain; /* should happen only once! */
283     }