ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readobj.c
Revision: 2.25
Committed: Tue Feb 7 20:28:16 2023 UTC (15 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R4, HEAD
Changes since 2.24: +8 -1 lines
Log Message:
perf: added calls to flockfile()/funlockfile() for more efficient reading

File Contents

# User Rev Content
1 greg 1.1 #ifndef lint
2 greg 2.25 static const char RCSid[] = "$Id: readobj.c,v 2.24 2020/10/17 16:39:23 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.22 OBJECT alias;
132 greg 1.7 strcpy(sbuf, "EOF");
133     fgetword(sbuf, MAXSTR, fp);
134 greg 1.1 if ((alias = modifier(sbuf)) == OVOID) {
135 greg 2.11 sprintf(errmsg, "(%s): bad reference \"%s\"",
136     name, sbuf);
137     objerror(objp, USER, errmsg);
138     }
139     if (objp->omod == OALIAS ||
140     objp->omod == objptr(alias)->omod) {
141     objp->omod = alias;
142     } else {
143     objp->oargs.sarg = (char **)malloc(sizeof(char *));
144     if (objp->oargs.sarg == NULL)
145     error(SYSTEM, "out of memory in getobject");
146     objp->oargs.nsargs = 1;
147     objp->oargs.sarg[0] = savestr(sbuf);
148 greg 1.1 }
149 greg 1.6 } else if ((rval = readfargs(&objp->oargs, fp)) == 0) {
150 greg 1.1 sprintf(errmsg, "(%s): bad arguments", name);
151     objerror(objp, USER, errmsg);
152 greg 1.6 } else if (rval < 0) {
153     sprintf(errmsg, "(%s): error reading scene", name);
154     error(SYSTEM, errmsg);
155 greg 1.1 }
156 greg 2.11 if (objp->omod == OALIAS) {
157     sprintf(errmsg, "(%s): inappropriate use of '%s' modifier",
158     name, ALIASMOD);
159     objerror(objp, USER, errmsg);
160     }
161 greg 1.1 /* initialize */
162     objp->os = NULL;
163    
164     insertobject(obj); /* add to global structure */
165 greg 2.11 #undef OALIAS
166 greg 1.1 }
167    
168    
169 greg 2.10 OBJECT
170 greg 2.22 newobject(void) /* get a new object */
171 greg 1.1 {
172 greg 2.22 int i;
173 greg 1.1
174 gwlarson 2.7 if ((nobjects & (OBJBLKSIZ-1)) == 0) { /* new block */
175 greg 1.1 errno = 0;
176 gwlarson 2.7 i = nobjects >> OBJBLKSHFT;
177 greg 1.1 if (i >= MAXOBJBLK)
178     return(OVOID);
179 greg 2.8 objblock[i] = (OBJREC *)calloc(OBJBLKSIZ, sizeof(OBJREC));
180 greg 1.1 if (objblock[i] == NULL)
181     return(OVOID);
182     }
183     return(nobjects++);
184 greg 2.8 }
185    
186     void
187 greg 2.22 freeobjects( /* free a range of objects */
188     int firstobj,
189     int nobjs
190     )
191 greg 2.8 {
192 greg 2.22 int obj;
193 greg 2.8 /* check bounds */
194     if (firstobj < 0)
195     return;
196     if (nobjs <= 0)
197     return;
198     if (firstobj + nobjs > nobjects)
199     return;
200     /* clear objects */
201     for (obj = firstobj+nobjs; obj-- > firstobj; ) {
202 greg 2.22 OBJREC *o = objptr(obj);
203 greg 2.8 free_os(o); /* free client memory */
204     freeqstr(o->oname);
205     freefargs(&o->oargs);
206 schorsch 2.16 memset((void *)o, '\0', sizeof(OBJREC));
207 greg 2.8 }
208     /* free objects off end */
209     for (obj = nobjects; obj-- > 0; )
210     if (objptr(obj)->oname != NULL)
211     break;
212 greg 2.24 if (++obj >= nobjects)
213     return;
214 greg 2.8 while (nobjects > obj) /* free empty end blocks */
215     if ((--nobjects & (OBJBLKSIZ-1)) == 0) {
216     int i = nobjects >> OBJBLKSHFT;
217     free((void *)objblock[i]);
218     objblock[i] = NULL;
219     }
220 greg 2.24 truncobjndx(); /* truncate modifier look-up */
221 greg 1.1 }