ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/trans.c
Revision: 2.2
Committed: Sat Feb 22 02:07:23 2003 UTC (21 years, 7 months ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad3R5
Changes since 2.1: +3 -4 lines
Log Message:
Changes and check-in for 3.5 release
Includes new source files and modifications not recorded for many years
See ray/doc/notes/ReleaseNotes for notes between 3.1 and 3.5 release

File Contents

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