Back to index

radiance  4R0+20100331
header.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: header.c,v 2.25 2009/05/21 18:08:43 greg Exp $";
00003 #endif
00004 /*
00005  *  header.c - routines for reading and writing information headers.
00006  *
00007  *  Externals declared in resolu.h
00008  *
00009  *  newheader(t,fp)  start new information header identified by string t
00010  *  headidval(r,s)   copy header identifier value in s to r
00011  *  dateval(t,s)     get capture date value as UTC
00012  *  gmtval(t,s)             get GMT as UTC
00013  *  fputdate(t,fp)   put out the given UTC
00014  *  fputnow(fp)             put out the current date and time
00015  *  printargs(ac,av,fp) print an argument list to fp, followed by '\n'
00016  *  formatval(r,s)   copy the format value in s to r
00017  *  fputformat(s,fp) write "FORMAT=%s" to fp
00018  *  getheader(fp,f,p)       read header from fp, calling f(s,p) on each line
00019  *  globmatch(pat, str)     check for glob match of str against pat
00020  *  checkheader(i,p,o)      check header format from i against p and copy to o
00021  *
00022  *  To copy header from input to output, use getheader(fin, fputs, fout)
00023  */
00024 
00025 #include "copyright.h"
00026 
00027 #include  <ctype.h>
00028 
00029 #include  "rtio.h"
00030 #include  "resolu.h"
00031 
00032 #define        MAXLINE      2048
00033 
00034 const char  HDRSTR[] = "#?";              /* information header magic number */
00035 
00036 const char  FMTSTR[] = "FORMAT=";  /* format identifier */
00037 
00038 const char  TMSTR[] = "CAPDATE=";  /* capture date identifier */
00039 const char  GMTSTR[] = "GMT=";            /* GMT identifier */
00040 
00041 static gethfunc mycheck;
00042 
00043 
00044 extern void
00045 newheader(           /* identifying line of information header */
00046        char  *s,
00047        FILE  *fp
00048 )
00049 {
00050        fputs(HDRSTR, fp);
00051        fputs(s, fp);
00052        putc('\n', fp);
00053 }
00054 
00055 
00056 extern int
00057 headidval(                  /* get header id (return true if is id) */
00058        char  *r,
00059        char   *s
00060 )
00061 {
00062        const char  *cp = HDRSTR;
00063 
00064        while (*cp) if (*cp++ != *s++) return(0);
00065        if (r == NULL) return(1);
00066        while (*s && !isspace(*s)) *r++ = *s++;
00067        *r = '\0';
00068        return(1);
00069 }
00070 
00071 
00072 extern int
00073 dateval(             /* convert capture date line to UTC */
00074        time_t *tloc,
00075        char   *s
00076 )
00077 {
00078        struct tm     tms;
00079        const char    *cp = TMSTR;
00080 
00081        while (*cp) if (*cp++ != *s++) return(0);
00082        while (isspace(*s)) s++;
00083        if (!*s) return(0);
00084        if (sscanf(s, "%d:%d:%d %d:%d:%d",
00085                      &tms.tm_year, &tms.tm_mon, &tms.tm_mday,
00086                      &tms.tm_hour, &tms.tm_min, &tms.tm_sec) != 6)
00087               return(0);
00088        if (tloc == NULL)
00089               return(1);
00090        tms.tm_mon--;
00091        tms.tm_year -= 1900;
00092        tms.tm_isdst = -1;   /* ask mktime() to figure out DST */
00093        *tloc = mktime(&tms);
00094        return(1);
00095 }
00096 
00097 
00098 extern int
00099 gmtval(                     /* convert GMT date line to UTC */
00100        time_t *tloc,
00101        char   *s
00102 )
00103 {
00104        struct tm     tms;
00105        const char    *cp = GMTSTR;
00106 
00107        while (*cp) if (*cp++ != *s++) return(0);
00108        while (isspace(*s)) s++;
00109        if (!*s) return(0);
00110        if (sscanf(s, "%d:%d:%d %d:%d:%d",
00111                      &tms.tm_year, &tms.tm_mon, &tms.tm_mday,
00112                      &tms.tm_hour, &tms.tm_min, &tms.tm_sec) != 6)
00113               return(0);
00114        if (tloc == NULL)
00115               return(1);
00116        tms.tm_mon--;
00117        tms.tm_year -= 1900;
00118        *tloc = timegm(&tms);
00119        return(1);
00120 }
00121 
00122 
00123 extern void
00124 fputdate(            /* write out the given time value (local & GMT) */
00125        time_t tv,
00126        FILE   *fp
00127 )
00128 {
00129        struct tm     *tms;
00130 
00131        tms = localtime(&tv);
00132        if (tms != NULL)
00133               fprintf(fp, "%s %04d:%02d:%02d %02d:%02d:%02d\n", TMSTR,
00134                             tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday,
00135                             tms->tm_hour, tms->tm_min, tms->tm_sec);
00136        tms = gmtime(&tv);
00137        if (tms != NULL)
00138               fprintf(fp, "%s %04d:%02d:%02d %02d:%02d:%02d\n", GMTSTR,
00139                             tms->tm_year+1900, tms->tm_mon+1, tms->tm_mday,
00140                             tms->tm_hour, tms->tm_min, tms->tm_sec);
00141 }
00142 
00143 
00144 extern void
00145 fputnow(                    /* write out the current time */
00146        FILE   *fp
00147 )
00148 {
00149        time_t tv;
00150        time(&tv);
00151        fputdate(tv, fp);
00152 }
00153 
00154 
00155 extern void
00156 printargs(           /* print arguments to a file */
00157        int  ac,
00158        char  **av,
00159        FILE  *fp
00160 )
00161 {
00162        while (ac-- > 0) {
00163               fputword(*av++, fp);
00164               fputc(ac ? ' ' : '\n', fp);
00165        }
00166 }
00167 
00168 
00169 extern int
00170 formatval(                  /* get format value (return true if format) */
00171        char  *r,
00172        char  *s
00173 )
00174 {
00175        const char  *cp = FMTSTR;
00176 
00177        while (*cp) if (*cp++ != *s++) return(0);
00178        while (isspace(*s)) s++;
00179        if (!*s) return(0);
00180        if (r == NULL) return(1);
00181        do
00182               *r++ = *s++;
00183        while(*s && !isspace(*s));
00184        *r = '\0';
00185        return(1);
00186 }
00187 
00188 
00189 extern void
00190 fputformat(          /* put out a format value */
00191        char  *s,
00192        FILE  *fp
00193 )
00194 {
00195        fputs(FMTSTR, fp);
00196        fputs(s, fp);
00197        putc('\n', fp);
00198 }
00199 
00200 
00201 extern int
00202 getheader(           /* get header from file */
00203        FILE  *fp,
00204        gethfunc *f,
00205        void  *p
00206 )
00207 {
00208        char  buf[MAXLINE];
00209 
00210        for ( ; ; ) {
00211               buf[MAXLINE-2] = '\n';
00212               if (fgets(buf, MAXLINE, fp) == NULL)
00213                      return(-1);
00214               if (buf[0] == '\n')
00215                      return(0);
00216 #ifdef MSDOS
00217               if (buf[0] == '\r' && buf[1] == '\n')
00218                      return(0);
00219 #endif
00220               if (buf[MAXLINE-2] != '\n') {
00221                      ungetc(buf[MAXLINE-2], fp); /* prevent false end */
00222                      buf[MAXLINE-2] = '\0';
00223               }
00224               if (f != NULL && (*f)(buf, p) < 0)
00225                      return(-1);
00226        }
00227 }
00228 
00229 
00230 struct check {
00231        FILE   *fp;
00232        char   fs[64];
00233 };
00234 
00235 
00236 static int
00237 mycheck(                    /* check a header line for format info. */
00238        char  *s,
00239        void  *cp
00240 )
00241 {
00242        if (!formatval(((struct check*)cp)->fs, s)
00243                      && ((struct check*)cp)->fp != NULL) {
00244               fputs(s, ((struct check*)cp)->fp);
00245        }
00246        return(0);
00247 }
00248 
00249 
00250 extern int
00251 globmatch(                  /* check for match of s against pattern p */
00252        char   *p,
00253        char   *s
00254 )
00255 {
00256        int    setmatch;
00257 
00258        do {
00259               switch (*p) {
00260               case '?':                   /* match any character */
00261                      if (!*s++)
00262                             return(0);
00263                      break;
00264               case '*':                   /* match any string */
00265                      while (p[1] == '*') p++;
00266                      do
00267                             if ( (p[1]=='?' || p[1]==*s) &&
00268                                           globmatch(p+1,s) )
00269                                    return(1);
00270                      while (*s++);
00271                      return(0);
00272               case '[':                   /* character set */
00273                      setmatch = *s == *++p;
00274                      if (!*p)
00275                             return(0);
00276                      while (*++p != ']') {
00277                             if (!*p)
00278                                    return(0);
00279                             if (*p == '-') {
00280                                    setmatch += p[-1] <= *s && *s <= p[1];
00281                                    if (!*++p)
00282                                           break;
00283                             } else
00284                                    setmatch += *p == *s;
00285                      }
00286                      if (!setmatch)
00287                             return(0);
00288                      s++;
00289                      break;
00290               case '\\':                  /* literal next */
00291                      p++;
00292               /* fall through */
00293               default:                    /* normal character */
00294                      if (*p != *s)
00295                             return(0);
00296                      s++;
00297                      break;
00298               }
00299        } while (*p++);
00300        return(1);
00301 }
00302 
00303 
00304 /*
00305  * Checkheader(fin,fmt,fout) returns a value of 1 if the input format
00306  * matches the specification in fmt, 0 if no input format was found,
00307  * and -1 if the input format does not match or there is an
00308  * error reading the header.  If fmt is empty, then -1 is returned
00309  * if any input format is found (or there is an error), and 0 otherwise.
00310  * If fmt contains any '*' or '?' characters, then checkheader
00311  * does wildcard expansion and copies a matching result into fmt.
00312  * Be sure that fmt is big enough to hold the match in such cases,
00313  * and that it is not a static, read-only string!
00314  * The input header (minus any format lines) is copied to fout
00315  * if fout is not NULL.
00316  */
00317 
00318 extern int
00319 checkheader(
00320        FILE  *fin,
00321        char  *fmt,
00322        FILE  *fout
00323 )
00324 {
00325        struct check  cdat;
00326        char   *cp;
00327 
00328        cdat.fp = fout;
00329        cdat.fs[0] = '\0';
00330        if (getheader(fin, mycheck, &cdat) < 0)
00331               return(-1);
00332        if (!cdat.fs[0])
00333               return(0);
00334        for (cp = fmt; *cp; cp++)          /* check for globbing */
00335               if ((*cp == '?') | (*cp == '*')) {
00336                      if (globmatch(fmt, cdat.fs)) {
00337                             strcpy(fmt, cdat.fs);
00338                             return(1);
00339                      } else
00340                             return(-1);
00341               }
00342        return(strcmp(fmt, cdat.fs) ? -1 : 1);    /* literal match */
00343 }