ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/trans.c
Revision: 2.6
Committed: Tue Mar 20 18:45:04 2018 UTC (6 years, 1 month ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad5R2
Changes since 2.5: +2 -1 lines
Log Message:
Added missing rtio.h include to redefine getc, putc, etc.

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: trans.c,v 2.5 2003/11/15 17:54:06 schorsch Exp $";
3 #endif
4 /*
5 * Translator utilities
6 *
7 * Greg Ward
8 */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <string.h>
13
14 #include "rterror.h"
15 #include "rtio.h"
16 #include "trans.h"
17
18 static int idcmp(ID *id1, ID *id2);
19 static void fputidlist(IDLIST *qp, FILE *fp);
20 static int qtype(char *qnm, register QLIST *qlp);
21
22 extern int
23 fgetid( /* read an id up to char in dls from fp */
24 ID *idp,
25 char *dls,
26 register FILE *fp
27 )
28 {
29 char dset[256/8];
30 char buf[MAXSTR];
31 register int c;
32 register char *cp;
33 /* create delimiter set */
34 for (cp = dset+sizeof(dset); cp-- > dset; )
35 *cp = 0;
36 for (cp = dls; *cp; cp++)
37 dset[*cp>>3] |= 1<<(*cp&7);
38 /* get characters up to delimiter */
39 cp = buf;
40 while ((c = getc(fp)) != EOF && !(dset[c>>3] & 1<<(c&7)))
41 *cp++ = c;
42 /* check for empty */
43 if (cp == buf) {
44 if (c == EOF)
45 return(EOF);
46 idp->number = 0;
47 idp->name = NULL;
48 return(0);
49 }
50 /* truncate space at end */
51 while (cp[-1] == ' ' || cp[-1] == '\t')
52 cp--;
53 *cp = '\0';
54 /* skip white space at beginning */
55 for (cp = buf; *cp && (*cp == ' ' || *cp == '\t'); cp++)
56 ;
57 /* assign value */
58 idp->number = atoi(cp);
59 idp->name = NULL;
60 /* check for ghost string */
61 if (!*cp)
62 return(0);
63 /* check for name */
64 if (idp->number == 0 && *cp != '0')
65 idp->name = savestr(cp);
66 return(0);
67 }
68
69
70 extern int
71 findid( /* find (or insert) id in list */
72 register IDLIST *idl,
73 ID *idp,
74 int insert
75 )
76 {
77 int upper, lower;
78 register int cm, i;
79 /* binary search */
80 lower = 0;
81 upper = cm = idl->nids;
82 while ((i = (lower + upper) >> 1) != cm) {
83 cm = idcmp(idp, &idl->id[i]);
84 if (cm > 0)
85 lower = i;
86 else if (cm < 0)
87 upper = i;
88 else
89 return(i);
90 cm = i;
91 }
92 if (!insert)
93 return(-1);
94 if (idl->nids == 0) { /* create new list */
95 idl->id = (ID *)malloc(sizeof(ID));
96 if (idl->id == NULL)
97 goto memerr;
98 } else { /* grow old list */
99 idl->id = (ID *)realloc((void *)idl->id,(idl->nids+1)*sizeof(ID));
100 if (idl->id == NULL)
101 goto memerr;
102 for (i = idl->nids; i > upper; i--) {
103 idl->id[i].number = idl->id[i-1].number;
104 idl->id[i].name = idl->id[i-1].name;
105 }
106 }
107 idl->nids++; /* insert new element */
108 idl->id[i].number = idp->number;
109 if (idp->name == NULL)
110 idl->id[i].name = NULL;
111 else
112 idl->id[i].name = savestr(idp->name);
113 return(i);
114 memerr:
115 eputs("Out of memory in findid\n");
116 quit(1);
117 return -1; /* pro forma return */
118 }
119
120
121 static int
122 idcmp( /* compare two identifiers */
123 register ID *id1,
124 register ID *id2
125 )
126 {
127 /* names are greater than numbers */
128 if (id1->name == NULL)
129 if (id2->name == NULL)
130 return(id1->number - id2->number);
131 else
132 return(-1);
133 else
134 if (id2->name == NULL)
135 return(1);
136 else
137 return(strcmp(id1->name, id2->name));
138 }
139
140
141 extern void
142 write_quals( /* write out qualifier lists */
143 QLIST *qlp,
144 IDLIST idl[],
145 FILE *fp
146 )
147 {
148 int i;
149
150 for (i = 0; i < qlp->nquals; i++)
151 if (idl[i].nids > 0) {
152 fprintf(fp, "qualifier %s begin\n", qlp->qual[i]);
153 fputidlist(&idl[i], fp);
154 fprintf(fp, "end\n");
155 }
156 }
157
158
159 static void
160 fputidlist( /* put id list out to fp */
161 IDLIST *qp,
162 FILE *fp
163 )
164 {
165 int fi;
166 register int i;
167 /* print numbers/ranges */
168 fi = 0;
169 for (i = 0; i < qp->nids && qp->id[i].name == NULL; i++)
170 if (i > 0 && qp->id[i].number > qp->id[i-1].number+1) {
171 if (i > fi+1)
172 fprintf(fp, "[%d:%d]\n", qp->id[fi].number,
173 qp->id[i-1].number);
174 else
175 fprintf(fp, "%d\n", qp->id[fi].number);
176 fi = i;
177 }
178 if (i-1 > fi)
179 fprintf(fp, "[%d:%d]\n", qp->id[fi].number,
180 qp->id[i-1].number);
181 else if (i > 0)
182 fprintf(fp, "%d\n", qp->id[fi].number);
183 for ( ; i < qp->nids; i++)
184 fprintf(fp, "\"%s\"\n", qp->id[i].name);
185 }
186
187
188 RULEHD *
189 getmapping( /* read in mapping file */
190 char *file,
191 QLIST *qlp
192 )
193 {
194 char *err;
195 register int c;
196 RULEHD *mp = NULL;
197 int nrules = 0;
198 register RULEHD *rp;
199 register int qt;
200 char buf[MAXSTR];
201 FILE *fp;
202
203 if ((fp = fopen(file, "r")) == NULL) {
204 eputs(file);
205 eputs(": cannot open\n");
206 quit(1);
207 }
208 /* get each rule */
209 while (fscanf(fp, " %[^ ;\n]", buf) == 1) {
210 if (buf[0] == '#') { /* comment */
211 while ((c = getc(fp)) != EOF && c != '\n')
212 ;
213 continue;
214 }
215 rp = (RULEHD *)calloc(1, rulsiz(qlp->nquals));
216 if (rp == NULL)
217 goto memerr;
218 rp->mnam = savestr(buf);
219 for ( ; ; ) { /* get conditions */
220 while ((c = getc(fp)) != '(')
221 if (c == ';' || c == EOF)
222 goto endloop;
223 if (fscanf(fp, " %s ", buf) != 1) {
224 err = "missing variable";
225 goto fmterr;
226 }
227 if ((qt = qtype(buf, qlp)) == -1) {
228 err = "unknown variable";
229 goto fmterr;
230 }
231 if (rp->qflg & FL(qt)) {
232 err = "variable repeated";
233 goto fmterr;
234 }
235 rp->qflg |= FL(qt);
236 c = getc(fp);
237 switch (c) {
238 case '"': /* id name */
239 if (fscanf(fp, "%[^\"]\" )", buf) != 1) {
240 err = "bad string value";
241 goto fmterr;
242 }
243 idm(rp)[qt].nam = savestr(buf);
244 break;
245 case '[': /* id range */
246 if (fscanf(fp, "%d : %d ] )", &idm(rp)[qt].min,
247 &idm(rp)[qt].max) != 2) {
248 err = "bad range value";
249 goto fmterr;
250 }
251 if (idm(rp)[qt].min > idm(rp)[qt].max) {
252 err = "reverse range value";
253 goto fmterr;
254 }
255 break;
256 default: /* id number? */
257 if ((c < '0' || c > '9') && c != '-') {
258 err = "unrecognizable value";
259 goto fmterr;
260 }
261 ungetc(c, fp);
262 if (fscanf(fp, "%d )", &idm(rp)[qt].min) != 1) {
263 err = "bad number id";
264 goto fmterr;
265 }
266 idm(rp)[qt].max = idm(rp)[qt].min;
267 break;
268 }
269 }
270 endloop:
271 rp->next = mp;
272 mp = rp;
273 nrules++;
274 }
275 fclose(fp);
276 return(mp);
277 fmterr:
278 sprintf(buf, "%s: %s for rule %d\n", file, err, nrules+1);
279 eputs(buf);
280 quit(1);
281 memerr:
282 eputs("Out of memory in getmapping\n");
283 quit(1);
284 return NULL; /* pro forma return */
285 }
286
287
288 static int
289 qtype( /* return number for qualifier name */
290 char *qnm,
291 register QLIST *qlp
292 )
293 {
294 register int i;
295
296 for (i = 0; i < qlp->nquals; i++)
297 if (!strcmp(qnm, qlp->qual[i]))
298 return(i);
299 return(-1);
300 }
301
302
303 extern int
304 matchid( /* see if we match an id */
305 register ID *it,
306 register IDMATCH *im
307 )
308 {
309 if (it->name == NULL) {
310 if (im->nam != NULL)
311 return(0);
312 return(it->number >= im->min && it->number <= im->max);
313 }
314 if (im->nam == NULL)
315 return(0);
316 return(!strcmp(it->name, im->nam));
317 }