ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/header.c
Revision: 2.25
Committed: Thu May 21 18:08:43 2009 UTC (15 years ago) by greg
Content type: text/plain
Branch: MAIN
CVS Tags: rad4R0
Changes since 2.24: +52 -49 lines
Log Message:
Added GPS header information (GMT and Latitude/Longitude)

File Contents

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