ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/cv/trans.c
Revision: 2.5
Committed: Sat Nov 15 17:54:06 2003 UTC (20 years, 11 months ago) by schorsch
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R2P2, rad5R0, rad5R1, rad3R7P2, rad3R7P1, rad4R2, rad4R1, rad4R0, rad3R6, rad3R6P1, rad3R8, rad3R9, rad4R2P1
Changes since 2.4: +25 -24 lines
Log Message:
Continued ANSIfication and reduced compile warnings.

File Contents

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