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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.5 static const char RCSid[] = "$Id: trans.c,v 2.4 2003/06/08 12:03:09 schorsch Exp $";
3 greg 1.1 #endif
4     /*
5     * Translator utilities
6     *
7     * Greg Ward
8     */
9    
10     #include <stdio.h>
11 greg 2.2 #include <stdlib.h>
12 schorsch 2.4 #include <string.h>
13 greg 1.1
14 schorsch 2.5 #include "rterror.h"
15 greg 1.1 #include "trans.h"
16    
17 schorsch 2.4 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 schorsch 2.5 extern int
22 schorsch 2.4 fgetid( /* read an id up to char in dls from fp */
23 schorsch 2.5 ID *idp,
24     char *dls,
25     register FILE *fp
26 schorsch 2.4 )
27 greg 1.1 {
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 schorsch 2.5 extern int
70 schorsch 2.4 findid( /* find (or insert) id in list */
71 schorsch 2.5 register IDLIST *idl,
72     ID *idp,
73     int insert
74 schorsch 2.4 )
75 greg 1.1 {
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 greg 2.3 idl->id = (ID *)realloc((void *)idl->id,(idl->nids+1)*sizeof(ID));
99 greg 1.1 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 schorsch 2.4 return -1; /* pro forma return */
117 greg 1.1 }
118    
119    
120 schorsch 2.4 static int
121     idcmp( /* compare two identifiers */
122 schorsch 2.5 register ID *id1,
123     register ID *id2
124 schorsch 2.4 )
125 greg 1.1 {
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 schorsch 2.5 extern void
141 schorsch 2.4 write_quals( /* write out qualifier lists */
142 schorsch 2.5 QLIST *qlp,
143     IDLIST idl[],
144     FILE *fp
145 schorsch 2.4 )
146 greg 1.1 {
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 schorsch 2.4 static void
159     fputidlist( /* put id list out to fp */
160 schorsch 2.5 IDLIST *qp,
161     FILE *fp
162 schorsch 2.4 )
163 greg 1.1 {
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 schorsch 2.4 getmapping( /* read in mapping file */
189 schorsch 2.5 char *file,
190     QLIST *qlp
191 schorsch 2.4 )
192 greg 1.1 {
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 schorsch 2.4 return NULL; /* pro forma return */
284 greg 1.1 }
285    
286    
287 schorsch 2.4 static int
288     qtype( /* return number for qualifier name */
289 schorsch 2.5 char *qnm,
290     register QLIST *qlp
291 schorsch 2.4 )
292 greg 1.1 {
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 schorsch 2.5 extern int
303 schorsch 2.4 matchid( /* see if we match an id */
304 schorsch 2.5 register ID *it,
305     register IDMATCH *im
306 schorsch 2.4 )
307 greg 1.1 {
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     }