ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/src/common/modobject.c
(Generate patch)

Comparing src/common/modobject.c (file contents):
Revision 1.1 by greg, Wed Jul 24 12:04:52 1991 UTC vs.
Revision 2.26 by greg, Sun Jun 22 17:21:37 2025 UTC

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

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines