ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/trans.c
Revision: 2.4
Committed: Sun Jun 8 12:03:09 2003 UTC (20 years, 9 months ago) by schorsch
Content type: text/plain
Branch: MAIN
Changes since 2.3: +49 -31 lines
Log Message:
Reduced compile warnings/errors on Windows.

File Contents

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