ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readobj.c
Revision: 2.23
Committed: Sat May 4 00:36:58 2019 UTC (4 years, 11 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R3
Changes since 2.22: +2 -2 lines
Log Message:
Eliminated cases where stdin was being closed

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: readobj.c,v 2.22 2017/04/08 03:56:44 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 while ((c = getc(infp)) != EOF) {
51 if (isspace(c))
52 continue;
53 if (c == '#') { /* comment */
54 fgets(buf, sizeof(buf), infp);
55 } else if (c == '!') { /* command */
56 ungetc(c, infp);
57 fgetline(buf, sizeof(buf), infp);
58 readobj(buf);
59 } else { /* object */
60 ungetc(c, infp);
61 getobject(inpspec, infp);
62 }
63 }
64 if (inpspec[0] == '!')
65 pclose(infp);
66 else if (infp != stdin)
67 fclose(infp);
68 if (nobjects == lastobj) {
69 sprintf(errmsg, "(%s): empty file", inpspec);
70 error(WARNING, errmsg);
71 }
72 }
73
74
75 void
76 getobject( /* read the next object */
77 char *name,
78 FILE *fp
79 )
80 {
81 #define OALIAS -2
82 OBJECT obj;
83 char sbuf[MAXSTR];
84 int rval;
85 OBJREC *objp;
86
87 if ((obj = newobject()) == OVOID)
88 error(SYSTEM, "out of object space");
89 objp = objptr(obj);
90 /* get modifier */
91 strcpy(sbuf, "EOF");
92 fgetword(sbuf, MAXSTR, fp);
93 if (strchr(sbuf, '\t')) {
94 sprintf(errmsg, "(%s): illegal tab in modifier \"%s\"",
95 name, sbuf);
96 error(USER, errmsg);
97 }
98 if (!strcmp(sbuf, VOIDID))
99 objp->omod = OVOID;
100 else if (!strcmp(sbuf, ALIASMOD))
101 objp->omod = OALIAS;
102 else if ((objp->omod = modifier(sbuf)) == OVOID) {
103 sprintf(errmsg, "(%s): undefined modifier \"%s\"", name, sbuf);
104 error(USER, errmsg);
105 }
106 /* get type */
107 strcpy(sbuf, "EOF");
108 fgetword(sbuf, MAXSTR, fp);
109 if ((objp->otype = otype(sbuf)) < 0) {
110 sprintf(errmsg, "(%s): unknown type \"%s\"", name, sbuf);
111 error(USER, errmsg);
112 }
113 /* get identifier */
114 sbuf[0] = '\0';
115 fgetword(sbuf, MAXSTR, fp);
116 if (strchr(sbuf, '\t')) {
117 sprintf(errmsg, "(%s): illegal tab in identifier \"%s\"",
118 name, sbuf);
119 error(USER, errmsg);
120 }
121 objp->oname = savqstr(sbuf);
122 /* get arguments */
123 if (objp->otype == MOD_ALIAS) {
124 OBJECT alias;
125 strcpy(sbuf, "EOF");
126 fgetword(sbuf, MAXSTR, fp);
127 if ((alias = modifier(sbuf)) == OVOID) {
128 sprintf(errmsg, "(%s): bad reference \"%s\"",
129 name, sbuf);
130 objerror(objp, USER, errmsg);
131 }
132 if (objp->omod == OALIAS ||
133 objp->omod == objptr(alias)->omod) {
134 objp->omod = alias;
135 } else {
136 objp->oargs.sarg = (char **)malloc(sizeof(char *));
137 if (objp->oargs.sarg == NULL)
138 error(SYSTEM, "out of memory in getobject");
139 objp->oargs.nsargs = 1;
140 objp->oargs.sarg[0] = savestr(sbuf);
141 }
142 } else if ((rval = readfargs(&objp->oargs, fp)) == 0) {
143 sprintf(errmsg, "(%s): bad arguments", name);
144 objerror(objp, USER, errmsg);
145 } else if (rval < 0) {
146 sprintf(errmsg, "(%s): error reading scene", name);
147 error(SYSTEM, errmsg);
148 }
149 if (objp->omod == OALIAS) {
150 sprintf(errmsg, "(%s): inappropriate use of '%s' modifier",
151 name, ALIASMOD);
152 objerror(objp, USER, errmsg);
153 }
154 /* initialize */
155 objp->os = NULL;
156
157 insertobject(obj); /* add to global structure */
158 #undef OALIAS
159 }
160
161
162 OBJECT
163 newobject(void) /* get a new object */
164 {
165 int i;
166
167 if ((nobjects & (OBJBLKSIZ-1)) == 0) { /* new block */
168 errno = 0;
169 i = nobjects >> OBJBLKSHFT;
170 if (i >= MAXOBJBLK)
171 return(OVOID);
172 objblock[i] = (OBJREC *)calloc(OBJBLKSIZ, sizeof(OBJREC));
173 if (objblock[i] == NULL)
174 return(OVOID);
175 }
176 return(nobjects++);
177 }
178
179 void
180 freeobjects( /* free a range of objects */
181 int firstobj,
182 int nobjs
183 )
184 {
185 int obj;
186 /* check bounds */
187 if (firstobj < 0)
188 return;
189 if (nobjs <= 0)
190 return;
191 if (firstobj + nobjs > nobjects)
192 return;
193 /* clear objects */
194 for (obj = firstobj+nobjs; obj-- > firstobj; ) {
195 OBJREC *o = objptr(obj);
196 free_os(o); /* free client memory */
197 freeqstr(o->oname);
198 freefargs(&o->oargs);
199 memset((void *)o, '\0', sizeof(OBJREC));
200 }
201 clearobjndx();
202 /* free objects off end */
203 for (obj = nobjects; obj-- > 0; )
204 if (objptr(obj)->oname != NULL)
205 break;
206 ++obj;
207 while (nobjects > obj) /* free empty end blocks */
208 if ((--nobjects & (OBJBLKSIZ-1)) == 0) {
209 int i = nobjects >> OBJBLKSHFT;
210 free((void *)objblock[i]);
211 objblock[i] = NULL;
212 }
213 }