ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/radiance/ray/src/common/header.c
Revision: 2.6
Committed: Mon Oct 16 10:53:46 1995 UTC (28 years, 6 months ago) by greg
Content type: text/plain
Branch: MAIN
Changes since 2.5: +11 -18 lines
Log Message:
changed copymatch() to globmatch(), which is more generally useful

File Contents

# Content
1 /* Copyright (c) 1994 Regents of the University of California */
2
3 #ifndef lint
4 static char SCCSid[] = "$SunId$ LBL";
5 #endif
6
7 /*
8 * header.c - routines for reading and writing information headers.
9 *
10 * 8/19/88
11 *
12 * newheader(t,fp) start new information header identified by string t
13 * isheadid(s) returns true if s is a header id line
14 * headidval(r,s) copy header identifier value in s to r
15 * printargs(ac,av,fp) print an argument list to fp, followed by '\n'
16 * isformat(s) returns true if s is of the form "FORMAT=*"
17 * formatval(r,s) copy the format value in s to r
18 * fputformat(s,fp) write "FORMAT=%s" to fp
19 * getheader(fp,f,p) read header from fp, calling f(s,p) on each line
20 * globmatch(pat, str) check for glob match of str against pat
21 * checkheader(i,p,o) check header format from i against p and copy to o
22 *
23 * To copy header from input to output, use getheader(fin, fputs, fout)
24 */
25
26 #include <stdio.h>
27 #include <ctype.h>
28
29 #define MAXLINE 512
30
31 #ifndef BSD
32 #define index strchr
33 #endif
34
35 extern char *index();
36
37 char HDRSTR[] = "#?"; /* information header magic number */
38
39 char FMTSTR[] = "FORMAT="; /* format identifier */
40
41
42 newheader(s, fp) /* identifying line of information header */
43 char *s;
44 register FILE *fp;
45 {
46 fputs(HDRSTR, fp);
47 fputs(s, fp);
48 putc('\n', fp);
49 }
50
51
52 int
53 headidval(r,s) /* get header id (return true if is id) */
54 register char *r, *s;
55 {
56 register char *cp = HDRSTR;
57
58 while (*cp) if (*cp++ != *s++) return(0);
59 if (r == NULL) return(1);
60 while (*s) *r++ = *s++;
61 *r = '\0';
62 return(1);
63 }
64
65
66 int
67 isheadid(s) /* check to see if line is header id */
68 char *s;
69 {
70 return(headidval(NULL, s));
71 }
72
73
74 printargs(ac, av, fp) /* print arguments to a file */
75 int ac;
76 char **av;
77 register FILE *fp;
78 {
79 int quote;
80
81 while (ac-- > 0) {
82 if (index(*av, ' ') != NULL) { /* quote it */
83 if (index(*av, '\'') != NULL)
84 quote = '"';
85 else
86 quote = '\'';
87 putc(quote, fp);
88 fputs(*av++, fp);
89 putc(quote, fp);
90 } else
91 fputs(*av++, fp);
92 putc(' ', fp);
93 }
94 putc('\n', fp);
95 }
96
97
98 int
99 formatval(r, s) /* get format value (return true if format) */
100 register char *r;
101 register char *s;
102 {
103 register char *cp = FMTSTR;
104
105 while (*cp) if (*cp++ != *s++) return(0);
106 while (isspace(*s)) s++;
107 if (!*s) return(0);
108 if (r == NULL) return(1);
109 do
110 *r++ = *s++;
111 while(*s && !isspace(*s));
112 *r = '\0';
113 return(1);
114 }
115
116
117 int
118 isformat(s) /* is line a format line? */
119 char *s;
120 {
121 return(formatval(NULL, s));
122 }
123
124
125 fputformat(s, fp) /* put out a format value */
126 char *s;
127 FILE *fp;
128 {
129 fputs(FMTSTR, fp);
130 fputs(s, fp);
131 putc('\n', fp);
132 }
133
134
135 int
136 getheader(fp, f, p) /* get header from file */
137 FILE *fp;
138 int (*f)();
139 char *p;
140 {
141 char buf[MAXLINE];
142
143 for ( ; ; ) {
144 buf[MAXLINE-2] = '\n';
145 if (fgets(buf, MAXLINE, fp) == NULL)
146 return(-1);
147 if (buf[0] == '\n')
148 return(0);
149 #ifdef MSDOS
150 if (buf[0] == '\r' && buf[1] == '\n')
151 return(0);
152 #endif
153 if (buf[MAXLINE-2] != '\n') {
154 ungetc(buf[MAXLINE-2], fp); /* prevent false end */
155 buf[MAXLINE-2] = '\0';
156 }
157 if (f != NULL)
158 (*f)(buf, p);
159 }
160 }
161
162
163 struct check {
164 FILE *fp;
165 char fs[64];
166 };
167
168
169 static
170 mycheck(s, cp) /* check a header line for format info. */
171 char *s;
172 register struct check *cp;
173 {
174 if (!formatval(cp->fs, s) && cp->fp != NULL)
175 fputs(s, cp->fp);
176 }
177
178
179 int
180 globmatch(pat, str) /* check for glob match of str against pat */
181 char *pat, *str;
182 {
183 register char *p = pat, *s = str;
184
185 do {
186 switch (*p) {
187 case '?': /* match any character */
188 if (!*s++)
189 return(0);
190 break;
191 case '*': /* match any string */
192 while (p[1] == '*') p++;
193 do
194 if ( (p[1]=='?' || p[1]==*s) &&
195 globmatch(p+1,s) )
196 return(1);
197 while (*s++);
198 return(0);
199 case '\\': /* literal next */
200 p++;
201 /* fall through */
202 default: /* normal character */
203 if (*p != *s)
204 return(0);
205 s++;
206 break;
207 }
208 } while (*p++);
209 return(1);
210 }
211
212
213 /*
214 * Checkheader(fin,fmt,fout) returns a value of 1 if the input format
215 * matches the specification in fmt, 0 if no input format was found,
216 * and -1 if the input format does not match or there is an
217 * error reading the header. If fmt is empty, then -1 is returned
218 * if any input format is found (or there is an error), and 0 otherwise.
219 * If fmt contains any '*' or '?' characters, then checkheader
220 * does wildcard expansion and copies a matching result into fmt.
221 * Be sure that fmt is big enough to hold the match in such cases!
222 * The input header (minus any format lines) is copied to fout
223 * if fout is not NULL.
224 */
225
226 int
227 checkheader(fin, fmt, fout)
228 FILE *fin;
229 char *fmt;
230 FILE *fout;
231 {
232 struct check cdat;
233
234 cdat.fp = fout;
235 cdat.fs[0] = '\0';
236 if (getheader(fin, mycheck, &cdat) < 0)
237 return(-1);
238 if (!cdat.fs[0])
239 return(0);
240 if (globmatch(fmt, cdat.fs)) {
241 strcpy(fmt, cdat.fs);
242 return(1);
243 }
244 return(-1);
245 }