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

# User Rev Content
1 greg 1.1 #ifndef lint
2 schorsch 2.4 static const char RCSid[] = "$Id: trans.c,v 2.3 2003/04/23 00:52:33 greg 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.4 #include "standard.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     fgetid( /* read an id up to char in dls from fp */
22     ID *idp,
23     char *dls,
24     register FILE *fp
25     )
26 greg 1.1 {
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 schorsch 2.4 findid( /* find (or insert) id in list */
70     register IDLIST *idl,
71     ID *idp,
72     int insert
73     )
74 greg 1.1 {
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 greg 2.3 idl->id = (ID *)realloc((void *)idl->id,(idl->nids+1)*sizeof(ID));
98 greg 1.1 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 schorsch 2.4 return -1; /* pro forma return */
116 greg 1.1 }
117    
118    
119 schorsch 2.4 static int
120     idcmp( /* compare two identifiers */
121     register ID *id1,
122     register ID *id2
123     )
124 greg 1.1 {
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 schorsch 2.4 void
140     write_quals( /* write out qualifier lists */
141     QLIST *qlp,
142     IDLIST idl[],
143     FILE *fp
144     )
145 greg 1.1 {
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 schorsch 2.4 static void
158     fputidlist( /* put id list out to fp */
159     IDLIST *qp,
160     FILE *fp
161     )
162 greg 1.1 {
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 schorsch 2.4 getmapping( /* read in mapping file */
188     char *file,
189     QLIST *qlp
190     )
191 greg 1.1 {
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 schorsch 2.4 return NULL; /* pro forma return */
283 greg 1.1 }
284    
285    
286 schorsch 2.4 static int
287     qtype( /* return number for qualifier name */
288     char *qnm,
289     register QLIST *qlp
290     )
291 greg 1.1 {
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 schorsch 2.4 int
302     matchid( /* see if we match an id */
303     register ID *it,
304     register IDMATCH *im
305     )
306 greg 1.1 {
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     }