ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readobj.c
Revision: 2.28
Committed: Tue Apr 22 14:51:29 2025 UTC (9 days, 16 hours ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: HEAD
Changes since 2.27: +2 -2 lines
Log Message:
fix: Changed some errors to warnings for pclose()

File Contents

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