ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/header.c
Revision: 2.16
Committed: Fri Jun 27 06:53:21 2003 UTC (20 years, 10 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.15: +5 -2 lines
Log Message:
Broke standard.h into rtio.h, rterror.h, rtmath.h, and rtmisc.h

File Contents

# Content
1 #ifndef lint
2 static const char RCSid[] = "$Id: header.c,v 2.15 2003/06/20 00:25:49 greg Exp $";
3 #endif
4 /*
5 * header.c - routines for reading and writing information headers.
6 *
7 * Externals declared in resolu.h
8 *
9 * newheader(t,fp) start new information header identified by string t
10 * isheadid(s) returns true if s is a header id line
11 * headidval(r,s) copy header identifier value in s to r
12 * dateval(t,s) get capture date value
13 * isdate(s) returns true if s is a date line
14 * fputdate(t,fp) put out the given capture date and time
15 * fputnow(fp) put out the current date and time
16 * printargs(ac,av,fp) print an argument list to fp, followed by '\n'
17 * isformat(s) returns true if s is of the form "FORMAT=*"
18 * formatval(r,s) copy the format value in s to r
19 * fputformat(s,fp) write "FORMAT=%s" to fp
20 * getheader(fp,f,p) read header from fp, calling f(s,p) on each line
21 * globmatch(pat, str) check for glob match of str against pat
22 * checkheader(i,p,o) check header format from i against p and copy to o
23 *
24 * To copy header from input to output, use getheader(fin, fputs, fout)
25 */
26
27 #include "copyright.h"
28 #include "resolu.h"
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <time.h>
33 #include <ctype.h>
34
35 #define MAXLINE 512
36
37 char HDRSTR[] = "#?"; /* information header magic number */
38
39 char FMTSTR[] = "FORMAT="; /* format identifier */
40
41 char TMSTR[] = "CAPDATE="; /* capture date identifier */
42
43 extern void fputword(char *s, FILE *fp);
44
45 static int mycheck();
46
47
48 void
49 newheader(s, fp) /* identifying line of information header */
50 char *s;
51 register FILE *fp;
52 {
53 fputs(HDRSTR, fp);
54 fputs(s, fp);
55 putc('\n', fp);
56 }
57
58
59 int
60 headidval(r,s) /* get header id (return true if is id) */
61 register char *r, *s;
62 {
63 register char *cp = HDRSTR;
64
65 while (*cp) if (*cp++ != *s++) return(0);
66 if (r == NULL) return(1);
67 while (*s && !isspace(*s)) *r++ = *s++;
68 *r = '\0';
69 return(1);
70 }
71
72
73 int
74 isheadid(s) /* check to see if line is header id */
75 char *s;
76 {
77 return(headidval(NULL, s));
78 }
79
80
81 int
82 dateval(tloc, s) /* get capture date value */
83 time_t *tloc;
84 char *s;
85 {
86 struct tm tms;
87 register char *cp = TMSTR;
88
89 while (*cp) if (*cp++ != *s++) return(0);
90 while (isspace(*s)) s++;
91 if (!*s) return(0);
92 if (sscanf(s, "%d:%d:%d %d:%d:%d",
93 &tms.tm_year, &tms.tm_mon, &tms.tm_mday,
94 &tms.tm_hour, &tms.tm_min, &tms.tm_sec) != 6)
95 return(0);
96 if (tloc == NULL)
97 return(1);
98 tms.tm_mon--;
99 tms.tm_year -= 1900;
100 tms.tm_isdst = -1; /* ask mktime() to figure out DST */
101 *tloc = mktime(&tms);
102 return(1);
103 }
104
105
106 int
107 isdate(s) /* is the given line a capture date? */
108 char *s;
109 {
110 return(dateval(NULL, s));
111 }
112
113
114 void
115 fputdate(tv, fp) /* write out the given time value */
116 time_t tv;
117 FILE *fp;
118 {
119 struct tm *tm = localtime(&tv);
120 if (tm == NULL)
121 return;
122 fprintf(fp, "%s %04d:%02d:%02d %02d:%02d:%02d\n", TMSTR,
123 tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday,
124 tm->tm_hour, tm->tm_min, tm->tm_sec);
125 }
126
127
128 void
129 fputnow(fp) /* write out the current time */
130 FILE *fp;
131 {
132 time_t tv;
133 time(&tv);
134 fputdate(tv, fp);
135 }
136
137
138 void
139 printargs(ac, av, fp) /* print arguments to a file */
140 int ac;
141 char **av;
142 FILE *fp;
143 {
144 while (ac-- > 0) {
145 fputword(*av++, fp);
146 fputc(ac ? ' ' : '\n', fp);
147 }
148 }
149
150
151 int
152 formatval(r, s) /* get format value (return true if format) */
153 register char *r;
154 register char *s;
155 {
156 register char *cp = FMTSTR;
157
158 while (*cp) if (*cp++ != *s++) return(0);
159 while (isspace(*s)) s++;
160 if (!*s) return(0);
161 if (r == NULL) return(1);
162 do
163 *r++ = *s++;
164 while(*s && !isspace(*s));
165 *r = '\0';
166 return(1);
167 }
168
169
170 int
171 isformat(s) /* is line a format line? */
172 char *s;
173 {
174 return(formatval(NULL, s));
175 }
176
177
178 void
179 fputformat(s, fp) /* put out a format value */
180 char *s;
181 FILE *fp;
182 {
183 fputs(FMTSTR, fp);
184 fputs(s, fp);
185 putc('\n', fp);
186 }
187
188
189 int
190 getheader(fp, f, p) /* get header from file */
191 FILE *fp;
192 int (*f)();
193 char *p;
194 {
195 char buf[MAXLINE];
196
197 for ( ; ; ) {
198 buf[MAXLINE-2] = '\n';
199 if (fgets(buf, MAXLINE, fp) == NULL)
200 return(-1);
201 if (buf[0] == '\n')
202 return(0);
203 #ifdef MSDOS
204 if (buf[0] == '\r' && buf[1] == '\n')
205 return(0);
206 #endif
207 if (buf[MAXLINE-2] != '\n') {
208 ungetc(buf[MAXLINE-2], fp); /* prevent false end */
209 buf[MAXLINE-2] = '\0';
210 }
211 if (f != NULL && (*f)(buf, p) < 0)
212 return(-1);
213 }
214 }
215
216
217 struct check {
218 FILE *fp;
219 char fs[64];
220 };
221
222
223 static int
224 mycheck(s, cp) /* check a header line for format info. */
225 char *s;
226 register struct check *cp;
227 {
228 if (!formatval(cp->fs, s) && cp->fp != NULL)
229 fputs(s, cp->fp);
230 return(0);
231 }
232
233
234 int
235 globmatch(p, s) /* check for match of s against pattern p */
236 register char *p, *s;
237 {
238 int setmatch;
239
240 do {
241 switch (*p) {
242 case '?': /* match any character */
243 if (!*s++)
244 return(0);
245 break;
246 case '*': /* match any string */
247 while (p[1] == '*') p++;
248 do
249 if ( (p[1]=='?' || p[1]==*s) &&
250 globmatch(p+1,s) )
251 return(1);
252 while (*s++);
253 return(0);
254 case '[': /* character set */
255 setmatch = *s == *++p;
256 if (!*p)
257 return(0);
258 while (*++p != ']') {
259 if (!*p)
260 return(0);
261 if (*p == '-') {
262 setmatch += p[-1] <= *s && *s <= p[1];
263 if (!*++p)
264 break;
265 } else
266 setmatch += *p == *s;
267 }
268 if (!setmatch)
269 return(0);
270 s++;
271 break;
272 case '\\': /* literal next */
273 p++;
274 /* fall through */
275 default: /* normal character */
276 if (*p != *s)
277 return(0);
278 s++;
279 break;
280 }
281 } while (*p++);
282 return(1);
283 }
284
285
286 /*
287 * Checkheader(fin,fmt,fout) returns a value of 1 if the input format
288 * matches the specification in fmt, 0 if no input format was found,
289 * and -1 if the input format does not match or there is an
290 * error reading the header. If fmt is empty, then -1 is returned
291 * if any input format is found (or there is an error), and 0 otherwise.
292 * If fmt contains any '*' or '?' characters, then checkheader
293 * does wildcard expansion and copies a matching result into fmt.
294 * Be sure that fmt is big enough to hold the match in such cases,
295 * and that it is not a static, read-only string!
296 * The input header (minus any format lines) is copied to fout
297 * if fout is not NULL.
298 */
299
300 int
301 checkheader(fin, fmt, fout)
302 FILE *fin;
303 char *fmt;
304 FILE *fout;
305 {
306 struct check cdat;
307 register char *cp;
308
309 cdat.fp = fout;
310 cdat.fs[0] = '\0';
311 if (getheader(fin, mycheck, (char *)&cdat) < 0)
312 return(-1);
313 if (!cdat.fs[0])
314 return(0);
315 for (cp = fmt; *cp; cp++) /* check for globbing */
316 if (*cp == '?' | *cp == '*')
317 if (globmatch(fmt, cdat.fs)) {
318 strcpy(fmt, cdat.fs);
319 return(1);
320 } else
321 return(-1);
322 return(strcmp(fmt, cdat.fs) ? -1 : 1); /* literal match */
323 }