ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readobj.c
Revision: 2.29
Committed: Sat Jun 7 05:09:45 2025 UTC (13 days, 6 hours ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.28: +1 -2 lines
Log Message:
refactor: Put some declarations into "paths.h" and included in "platform.h"

File Contents

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