ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readobj.c
Revision: 2.26
Committed: Sat Dec 7 02:05:30 2024 UTC (5 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.25: +11 -7 lines
Log Message:
perf: Skip pointless pass-through aliases during scene file load

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.26 static const char RCSid[] = "$Id: readobj.c,v 2.25 2023/02/07 20:28:16 greg Exp $";
3 greg 1.1 #endif
4     /*
5     * readobj.c - routines for reading in object descriptions.
6     *
7 greg 2.8 * External symbols declared in object.h
8     */
9    
10 greg 2.9 #include "copyright.h"
11 greg 1.1
12 schorsch 2.13 #include <ctype.h>
13 schorsch 2.16 #include <string.h>
14 schorsch 2.14 #include <stdio.h>
15 schorsch 2.13
16 greg 2.17 #include "platform.h"
17 greg 2.21 #include "paths.h"
18 greg 1.1 #include "standard.h"
19     #include "object.h"
20     #include "otypes.h"
21    
22    
23     OBJREC *objblock[MAXOBJBLK]; /* our objects */
24 greg 1.4 OBJECT nobjects = 0; /* # of objects */
25 greg 1.1
26    
27 greg 2.8 void
28 greg 2.22 readobj( /* read in an object file or stream */
29     char *inpspec
30     )
31 greg 1.1 {
32 greg 2.4 OBJECT lastobj;
33 greg 1.1 FILE *infp;
34 greg 2.19 char buf[2048];
35 greg 2.22 int c;
36 greg 1.1
37 greg 2.4 lastobj = nobjects;
38     if (inpspec == NULL) {
39 greg 1.1 infp = stdin;
40 greg 2.4 inpspec = "standard input";
41     } else if (inpspec[0] == '!') {
42     if ((infp = popen(inpspec+1, "r")) == NULL) {
43     sprintf(errmsg, "cannot execute \"%s\"", inpspec);
44 greg 1.1 error(SYSTEM, errmsg);
45     }
46 greg 2.4 } else if ((infp = fopen(inpspec, "r")) == NULL) {
47     sprintf(errmsg, "cannot open scene file \"%s\"", inpspec);
48 greg 1.1 error(SYSTEM, errmsg);
49     }
50 greg 2.25 #ifdef getc_unlocked /* avoid stupid semaphores */
51     flockfile(infp);
52     #endif
53 greg 1.1 while ((c = getc(infp)) != EOF) {
54     if (isspace(c))
55     continue;
56     if (c == '#') { /* comment */
57     fgets(buf, sizeof(buf), infp);
58 greg 1.2 } else if (c == '!') { /* command */
59 greg 1.1 ungetc(c, infp);
60 greg 1.2 fgetline(buf, sizeof(buf), infp);
61 greg 1.1 readobj(buf);
62     } else { /* object */
63     ungetc(c, infp);
64 greg 2.4 getobject(inpspec, infp);
65 greg 1.1 }
66     }
67 greg 2.4 if (inpspec[0] == '!')
68 greg 1.1 pclose(infp);
69 greg 2.23 else if (infp != stdin)
70 greg 1.1 fclose(infp);
71 greg 2.25 #ifdef getc_unlocked
72     else
73     funlockfile(infp);
74     #endif
75 greg 2.4 if (nobjects == lastobj) {
76     sprintf(errmsg, "(%s): empty file", inpspec);
77     error(WARNING, errmsg);
78     }
79 greg 1.1 }
80    
81    
82 greg 2.8 void
83 greg 2.22 getobject( /* read the next object */
84     char *name,
85     FILE *fp
86     )
87 greg 1.1 {
88 greg 2.11 #define OALIAS -2
89 greg 1.1 OBJECT obj;
90     char sbuf[MAXSTR];
91 greg 1.6 int rval;
92 greg 2.22 OBJREC *objp;
93 greg 1.1
94     if ((obj = newobject()) == OVOID)
95     error(SYSTEM, "out of object space");
96     objp = objptr(obj);
97     /* get modifier */
98 greg 1.7 strcpy(sbuf, "EOF");
99     fgetword(sbuf, MAXSTR, fp);
100 greg 2.20 if (strchr(sbuf, '\t')) {
101     sprintf(errmsg, "(%s): illegal tab in modifier \"%s\"",
102     name, sbuf);
103     error(USER, errmsg);
104     }
105 greg 1.1 if (!strcmp(sbuf, VOIDID))
106     objp->omod = OVOID;
107 greg 2.11 else if (!strcmp(sbuf, ALIASMOD))
108     objp->omod = OALIAS;
109 greg 1.1 else if ((objp->omod = modifier(sbuf)) == OVOID) {
110     sprintf(errmsg, "(%s): undefined modifier \"%s\"", name, sbuf);
111     error(USER, errmsg);
112     }
113     /* get type */
114 greg 1.7 strcpy(sbuf, "EOF");
115     fgetword(sbuf, MAXSTR, fp);
116 greg 2.11 if ((objp->otype = otype(sbuf)) < 0) {
117 greg 1.1 sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf);
118     error(USER, errmsg);
119     }
120     /* get identifier */
121 greg 1.7 sbuf[0] = '\0';
122     fgetword(sbuf, MAXSTR, fp);
123 greg 2.20 if (strchr(sbuf, '\t')) {
124     sprintf(errmsg, "(%s): illegal tab in identifier \"%s\"",
125     name, sbuf);
126     error(USER, errmsg);
127     }
128 greg 1.1 objp->oname = savqstr(sbuf);
129     /* get arguments */
130 greg 2.11 if (objp->otype == MOD_ALIAS) {
131 greg 2.26 OBJECT ref;
132     OBJREC *rfp;
133 greg 1.7 strcpy(sbuf, "EOF");
134     fgetword(sbuf, MAXSTR, fp);
135 greg 2.26 if ((ref = modifier(sbuf)) == OVOID) {
136 greg 2.11 sprintf(errmsg, "(%s): bad reference \"%s\"",
137     name, sbuf);
138     objerror(objp, USER, errmsg);
139 greg 2.26 } /* skip pass-thru aliases */
140     while ((rfp=objptr(ref))->otype == MOD_ALIAS &&
141     !rfp->oargs.nsargs & (rfp->omod != OVOID))
142     ref = rfp->omod;
143    
144     if ((objp->omod == OALIAS) | (objp->omod == rfp->omod)) {
145     objp->omod = ref;
146 greg 2.11 } else {
147     objp->oargs.sarg = (char **)malloc(sizeof(char *));
148     if (objp->oargs.sarg == NULL)
149     error(SYSTEM, "out of memory in getobject");
150     objp->oargs.nsargs = 1;
151     objp->oargs.sarg[0] = savestr(sbuf);
152 greg 1.1 }
153 greg 1.6 } else if ((rval = readfargs(&objp->oargs, fp)) == 0) {
154 greg 1.1 sprintf(errmsg, "(%s): bad arguments", name);
155     objerror(objp, USER, errmsg);
156 greg 1.6 } else if (rval < 0) {
157     sprintf(errmsg, "(%s): error reading scene", name);
158     error(SYSTEM, errmsg);
159 greg 1.1 }
160 greg 2.11 if (objp->omod == OALIAS) {
161     sprintf(errmsg, "(%s): inappropriate use of '%s' modifier",
162     name, ALIASMOD);
163     objerror(objp, USER, errmsg);
164     }
165 greg 1.1 /* initialize */
166     objp->os = NULL;
167    
168     insertobject(obj); /* add to global structure */
169 greg 2.11 #undef OALIAS
170 greg 1.1 }
171    
172    
173 greg 2.10 OBJECT
174 greg 2.22 newobject(void) /* get a new object */
175 greg 1.1 {
176 greg 2.22 int i;
177 greg 1.1
178 gwlarson 2.7 if ((nobjects & (OBJBLKSIZ-1)) == 0) { /* new block */
179 greg 1.1 errno = 0;
180 gwlarson 2.7 i = nobjects >> OBJBLKSHFT;
181 greg 1.1 if (i >= MAXOBJBLK)
182     return(OVOID);
183 greg 2.8 objblock[i] = (OBJREC *)calloc(OBJBLKSIZ, sizeof(OBJREC));
184 greg 1.1 if (objblock[i] == NULL)
185     return(OVOID);
186     }
187     return(nobjects++);
188 greg 2.8 }
189    
190     void
191 greg 2.22 freeobjects( /* free a range of objects */
192     int firstobj,
193     int nobjs
194     )
195 greg 2.8 {
196 greg 2.22 int obj;
197 greg 2.8 /* check bounds */
198     if (firstobj < 0)
199     return;
200     if (nobjs <= 0)
201     return;
202     if (firstobj + nobjs > nobjects)
203     return;
204     /* clear objects */
205     for (obj = firstobj+nobjs; obj-- > firstobj; ) {
206 greg 2.22 OBJREC *o = objptr(obj);
207 greg 2.8 free_os(o); /* free client memory */
208     freeqstr(o->oname);
209     freefargs(&o->oargs);
210 schorsch 2.16 memset((void *)o, '\0', sizeof(OBJREC));
211 greg 2.8 }
212     /* free objects off end */
213     for (obj = nobjects; obj-- > 0; )
214     if (objptr(obj)->oname != NULL)
215     break;
216 greg 2.24 if (++obj >= nobjects)
217     return;
218 greg 2.8 while (nobjects > obj) /* free empty end blocks */
219     if ((--nobjects & (OBJBLKSIZ-1)) == 0) {
220     int i = nobjects >> OBJBLKSHFT;
221     free((void *)objblock[i]);
222     objblock[i] = NULL;
223     }
224 greg 2.24 truncobjndx(); /* truncate modifier look-up */
225 greg 1.1 }