ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/readobj.c
Revision: 2.20
Committed: Tue Mar 30 12:42:33 2010 UTC (14 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad4R2, rad4R1, rad4R2P1
Changes since 2.19: +11 -1 lines
Log Message:
Added check against tab in modifier or identifier, which breaks rtrace

File Contents

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