Back to index

radiance  4R0+20100331
loadvars.c
Go to the documentation of this file.
00001 #ifndef lint
00002 static const char    RCSid[] = "$Id: loadvars.c,v 2.14 2003/07/30 10:11:06 schorsch Exp $";
00003 #endif
00004 /*
00005  *  Routines for loading and checking variables from file.
00006  */
00007 
00008 #include "copyright.h"
00009 
00010 #include <stdio.h>
00011 #include <stdlib.h>
00012 #include <ctype.h>
00013 
00014 #include "standard.h"
00015 #include "vars.h"
00016 
00017 #define NOCHAR       127           /* constant for character to delete */
00018 
00019 extern char  *fgetline();
00020 
00021 
00022 void
00023 loadvars(rfname)            /* load variables into vv from file */
00024 char   *rfname;
00025 {
00026        FILE   *fp;
00027        char   buf[512];
00028        register char *cp;
00029 
00030        if (rfname == NULL)
00031               fp = stdin;
00032        else if ((fp = fopen(rfname, "r")) == NULL) {
00033               perror(rfname);
00034               quit(1);
00035        }
00036        while (fgetline(buf, sizeof(buf), fp) != NULL) {
00037               for (cp = buf; *cp; cp++) {
00038                      switch (*cp) {
00039                      case '\\':
00040                             *cp++ = NOCHAR;
00041                             continue;
00042                      case '#':
00043                             *cp = '\0';
00044                             break;
00045                      default:
00046                             continue;
00047                      }
00048                      break;
00049               }
00050               if (setvariable(buf, matchvar) < 0) {
00051                      fprintf(stderr, "%s: unknown variable: %s\n",
00052                                    rfname, buf);
00053                      quit(1);
00054               }
00055        }
00056        fclose(fp);
00057 }
00058 
00059 
00060 int
00061 setvariable(ass, mv)        /* assign variable according to string */
00062 register char *ass;
00063 VARIABLE      *(*mv)(char*);
00064 {
00065        char   varname[32];
00066        int    n;
00067        register char *cp;
00068        register VARIABLE    *vp;
00069        register int  i;
00070 
00071        while (isspace(*ass))              /* skip leading space */
00072               ass++;
00073        cp = varname;               /* extract name */
00074        while (cp < varname+sizeof(varname)-1
00075                      && *ass && !isspace(*ass) && *ass != '=')
00076               *cp++ = *ass++;
00077        *cp = '\0';
00078        if (!varname[0])
00079               return(0);    /* no variable name! */
00080                                    /* trim value */
00081        while (isspace(*ass) || *ass == '=')
00082               ass++;
00083        for (n = strlen(ass); n > 0; n--)
00084               if (!isspace(ass[n-1]))
00085                      break;
00086        if (!n)
00087               return(0);    /* no assignment */
00088                                    /* match variable from list */
00089        vp = (*mv)(varname);
00090        if (vp == NULL)
00091               return(-1);
00092                                    /* assign new value */
00093        if ( (i = vp->nass) ) {
00094               cp = vp->value;
00095               while (i--)
00096                      while (*cp++)
00097                             ;
00098               i = cp - vp->value;
00099               vp->value = (char *)realloc((void *)vp->value, i+n+1);
00100        } else
00101               vp->value = (char *)malloc(n+1);
00102        if (vp->value == NULL) {
00103               perror(progname);
00104               quit(1);
00105        }
00106        cp = vp->value+i;           /* copy value, squeezing spaces */
00107        *cp = *ass;
00108        for (i = 1; i <= n; i++) {
00109               if (ass[i] == NOCHAR)
00110                      continue;
00111               if (isspace(*cp))
00112                      while (isspace(ass[i]))
00113                             i++;
00114               *++cp = ass[i];
00115        }
00116        if (isspace(*cp))           /* remove trailing space */
00117               *cp = '\0';
00118        return(++vp->nass);
00119 }
00120 
00121 
00122 VARIABLE *
00123 matchvar(nam)               /* match a variable by its name */
00124 char   *nam;
00125 {
00126        int    n = strlen(nam);
00127        register int  i;
00128 
00129        for (i = 0; i < NVARS; i++)
00130               if (n >= vv[i].nick && !strncmp(nam, vv[i].name, n))
00131                      return(vv+i);
00132        return(NULL);
00133 }
00134 
00135 
00136 char *
00137 nvalue(vn, n)               /* return nth variable value */
00138 register int  vn;
00139 register int  n;
00140 {
00141        register char *cp;
00142 
00143        if ((vval(vn) == NULL) | (n < 0) | (n >= vdef(vn)))
00144               return(NULL);
00145        cp = vval(vn);
00146        while (n--)
00147               while (*cp++)
00148                      ;
00149        return(cp);
00150 }
00151 
00152 
00153 void
00154 checkvalues()               /* check assignments */
00155 {
00156        register int  i;
00157 
00158        for (i = 0; i < NVARS; i++)
00159               if (vv[i].fixval != NULL)
00160                      (*vv[i].fixval)(vv+i);
00161 }
00162 
00163 
00164 void
00165 onevalue(vp)                /* only one assignment for this variable */
00166 register VARIABLE    *vp;
00167 {
00168        if (vp->nass < 2)
00169               return;
00170        if (!nowarn)
00171               fprintf(stderr,
00172               "%s: warning - multiple assignment of variable '%s'\n",
00173                      progname, vp->name);
00174        do
00175               vp->value += strlen(vp->value)+1;
00176        while (--vp->nass > 1);
00177 }
00178 
00179 
00180 void
00181 catvalues(vp)               /* concatenate variable values */
00182 register VARIABLE    *vp;
00183 {
00184        register char *cp;
00185 
00186        if (vp->nass < 2)
00187               return;
00188        for (cp = vp->value; vp->nass > 1; vp->nass--) {
00189               while (*cp)
00190                      cp++;
00191               *cp++ = ' ';
00192        }
00193 }
00194 
00195 
00196 int
00197 badmatch(tv, cv)            /* case insensitive truncated comparison */
00198 register char *tv, *cv;
00199 {
00200        if (!*tv) return(1);        /* null string cannot match */
00201        do
00202               if (UPPER(*tv) != *cv++)
00203                      return(1);
00204        while (*++tv);
00205        return(0);           /* OK */
00206 }
00207 
00208 
00209 void
00210 boolvalue(vp)               /* check boolean for legal values */
00211 register VARIABLE    *vp;
00212 {
00213        if (!vp->nass) return;
00214        onevalue(vp);
00215        switch (UPPER(vp->value[0])) {
00216        case 'T':
00217               if (badmatch(vp->value, "TRUE")) break;
00218               return;
00219        case 'F':
00220               if (badmatch(vp->value, "FALSE")) break;
00221               return;
00222        }
00223        fprintf(stderr, "%s: illegal value for boolean variable '%s'\n",
00224                      progname, vp->name);
00225        quit(1);
00226 }
00227 
00228 
00229 void
00230 qualvalue(vp)               /* check qualitative var. for legal values */
00231 register VARIABLE    *vp;
00232 {
00233        if (!vp->nass) return;
00234        onevalue(vp);
00235        switch (UPPER(vp->value[0])) {
00236        case 'L':
00237               if (badmatch(vp->value, "LOW")) break;
00238               return;
00239        case 'M':
00240               if (badmatch(vp->value, "MEDIUM")) break;
00241               return;
00242        case 'H':
00243               if (badmatch(vp->value, "HIGH")) break;
00244               return;
00245        }
00246        fprintf(stderr, "%s: illegal value for qualitative variable '%s'\n",
00247                      progname, vp->name);
00248        quit(1);
00249 }
00250 
00251 
00252 void
00253 intvalue(vp)                /* check integer variable for legal values */
00254 register VARIABLE    *vp;
00255 {
00256        if (!vp->nass) return;
00257        onevalue(vp);
00258        if (isint(vp->value)) return;
00259        fprintf(stderr, "%s: illegal value for integer variable '%s'\n",
00260                      progname, vp->name);
00261        quit(1);
00262 }
00263 
00264 
00265 void
00266 fltvalue(vp)                /* check float variable for legal values */
00267 register VARIABLE    *vp;
00268 {
00269        if (!vp->nass) return;
00270        onevalue(vp);
00271        if (isflt(vp->value)) return;
00272        fprintf(stderr, "%s: illegal value for real variable '%s'\n",
00273                      progname, vp->name);
00274        quit(1);
00275 }
00276 
00277 
00278 void
00279 printvars(fp)               /* print variable values */
00280 register FILE *fp;
00281 {
00282        int    i, j, k, clipline;
00283        register char *cp;
00284 
00285        for (i = 0; i < NVARS; i++)        /* print each variable */
00286            for (j = 0; j < vdef(i); j++) {       /* print each assignment */
00287               fputs(vnam(i), fp);
00288               fputs("= ", fp);
00289               k = clipline = ( vv[i].fixval == catvalues ? 64 : 236 )
00290                             - strlen(vnam(i)) ;
00291               cp = nvalue(i, j);
00292               while (*cp) {
00293                   putc(*cp++, fp);
00294                   if (--k <= 0) {         /* line too long */
00295                      while (*cp && !isspace(*cp))
00296                          fputc(*cp++, fp);       /* finish this word */
00297                      if (*cp) {           /* start new line */
00298                          if (vv[i].fixval == catvalues) {
00299                             fputc('\n', fp);
00300                             fputs(vnam(i), fp);
00301                             fputc('=', fp);
00302                          } else
00303                             fputs(" \\\n", fp);
00304                          k = clipline;
00305                      }
00306                   }
00307               }
00308                fputc('\n', fp);
00309            }
00310        fflush(fp);
00311 }