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 (29 hours, 35 minutes 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

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