home *** CD-ROM | disk | FTP | other *** search
/ The World of Computer Software / World_Of_Computer_Software-02-385-Vol-1of3.iso / d / dots151.zip / GRAPHSRC.ZIP / CONFIG.C < prev    next >
C/C++ Source or Header  |  1990-07-05  |  6KB  |  197 lines

  1. /*
  2.     config - read graphics device driver configuration file
  3.  
  4.     Config reads command line-like switches from a configuration file. 
  5.     Switches may have arguments, but not optional arguments.  fname is
  6.     the name of the configuration file.  cpath is NULL, or a string
  7.     containing a series of directories (optionally ending with '/' or
  8.     '\\'), separated by semicolons.  pp points to an array of
  9.     structures, with one element per legal switch.  The array is
  10.     terminated by an element starting with a zero.  buf is a work array
  11.     of length bufsize.
  12.  
  13.     In the configuration file, parameters are represented by switches like
  14.     those used on the command line.  Switches introduced by '-' specify
  15.     final values of the corresponding parameters.  Use '+' rather than
  16.     '-' if the given values are to be defaults only, and the driver is
  17.     to ask the user for the final values.  Tokens (switches and parameters)
  18.     are separated by whitespace (spaces, tabs, or newlines).  A semicolon
  19.     denotes a comment which extends to the end of the line.
  20.  
  21.     If an illegal switch appears in the file, config prints an error
  22.     message to stderr and exits with an error.
  23.  
  24.     The item pp[i]->ask points to an integer which is set to zero if the
  25.     switch was introduced by '-'.  Note that, as in the example below,
  26.     more than one such item may point to the same integer.  This can
  27.     be used if two switches are mutually exclusive, and using either
  28.     one should prevent a user query.  Either pp[i]->ask or pp[i]->var
  29.     may be NULL.  (There would be no point to setting both to NULL,
  30.     since config could then record no information about the switch.)
  31.  
  32.     EXAMPLE...
  33.  
  34.     Typical switches are...
  35.         -p                            ;    portrait orientation
  36.         -l                            ;    landscape orientation
  37.         -o    <xoffset> <yoffset>        ;    offset from top left corner 
  38.         -s    <xsize> <ysize>            ;    plot size
  39.         -v    <num>                    ;    pen velocity
  40.  
  41.     ...which would be represented by this structure:
  42.  
  43.     PARAM parmv[] = {{'o', REAL, &offset_ask, offsetv, 2},
  44.                 {'s', REAL, &size_ask, sizev, 2},
  45.                 {'v', REAL, &vel_ask, &vel, 1},
  46.                 {'p', BOOLEAN, &orientation_ask, &portrait, 0},
  47.                 {'l', BOOLEAN, &orientation_ask, &landscape, 0},
  48.                 {'L', STRING, NULL, &plabel, 1},
  49.                 {'\0'}};
  50.  
  51.     The configuration file might contain:
  52.                 -v 17     ; velocity
  53.                 +o 0 1  ; offset (default only)
  54.                 -p        ; portrait orientation
  55.  
  56. */
  57. #include <stdio.h>
  58. #include <math.h>
  59. #include <string.h>
  60. #include "config.h"
  61.  
  62. static FILE *cfile = stdin;
  63.  
  64. static char *gettok(char *buf, int bufsize)
  65. {    static char separate[] = " \t\n";
  66.     char *s;
  67.     s = strtok(NULL, separate);
  68.     while(s == NULL)
  69.         {s = fgets(buf, bufsize, cfile);
  70.         if(s == NULL) return NULL;
  71.         s = strchr(buf, ';');
  72.         if(s != NULL) *s = 0;        /* zap the comment */
  73.         s = strtok(buf, separate);
  74.         }
  75.     return s;
  76. }
  77.  
  78. static cgripe(char *s, char *fname)
  79. {    fprintf(stderr, "illegal parameter %s in configuration file %s\n", 
  80.                                                                 s, fname);
  81.     exit(1);
  82. }
  83.  
  84. config(char *fname, char *cpath, PARAM *pp, char *buf, int bufsize)
  85. {    char c, *s;
  86.     int ask, found, i;
  87.     PARAM *np;
  88.     int *ip;
  89.     double *dp;
  90.     char *cp;
  91.     char **sp;
  92.  
  93.     if(fname == NULL) return;
  94.     buf[0] = 0;
  95.     while(1)
  96.         {strncat(buf, fname, bufsize - strlen(fname) - 2);
  97.         cfile = fopen(buf, "r");
  98.         if(cfile != NULL) break;                /* found configuration file */
  99.         if(cpath == NULL || *cpath == 0) 
  100.             return;                                /* no configuration file */
  101.         for (i = 0; *cpath && *cpath != ';'; i++) 
  102.             buf[i] = *cpath++;
  103.         if(*cpath) cpath++;                        /* step past the ';' */
  104.         if(i > 0)
  105.             {c = buf[i-1];
  106.             if(c != ':' && c != '\\' && c != '/') 
  107.                 buf[i++] = '/';                /* append '/' to path */
  108.             }
  109.         buf[i] = 0;
  110.         }
  111.     strtok("", " ");        /* force initial read from file */
  112.             
  113.     while((s = gettok(buf, bufsize)) != NULL)
  114.         {switch(s[0])
  115.             {case '-':    ask =   0; break;
  116.             case '+':    ask =   1; break;
  117.             default:    cgripe(s, fname);
  118.             }
  119.         for (np = pp, found = 0; np->flag; np++)
  120.             {if(s[1] != np->flag) continue;
  121.             if(np->var == NULL) continue;
  122.             found = 1;
  123.             if(np->ask != NULL) *np->ask = ask;
  124.             if((np->type == BOOLEAN) && (np->nvar == 0))
  125.                 {ip = (int *)np->var;
  126.                 *ip = (int)(s[2] != '-');
  127.                 }
  128.             ip = (int *)np->var;
  129.             dp = (double *)np->var;
  130.             cp = (char *)np->var;
  131.             sp = (char **)np->var;
  132.             for (i = 0; i < np->nvar ; i++)
  133.                 {s = gettok(buf, bufsize);
  134.                 if(s == NULL) return;
  135.  
  136.                 switch(np->type)
  137.                     {case BOOLEAN:    ip[i] = atoi(s); break;
  138.                     case CHARACTER:    cp[i] = s[0]; break;
  139.                     case STRING:    sp[i] = strdup(s); break;
  140.                     case REAL:        dp[i] = atof(s);
  141.                     }
  142.                 }
  143.             break;
  144.             }
  145.         if(!found) cgripe(s, fname);
  146.         }
  147. }
  148.  
  149. #ifdef MAIN
  150.  
  151. int offset_doubt = 1;
  152. int size_doubt = 1;
  153. int vel_doubt = 1;
  154. int orientation_doubt = 1;
  155. int do_doubt = 1;
  156.  
  157. double offsetv[2] = {2.,1.}, sizev[2] = {6.,3.}, vel = 12.;
  158. int portrait = 0, landscape = 0;
  159. char *plabel = "default_string";
  160.  
  161. PARAM parmv[] = {{'o', REAL, &offset_doubt, offsetv, 2},
  162.                 {'s', REAL, &size_doubt, sizev, 2},
  163.                 {'v', REAL, &vel_doubt, &vel, 1},
  164.                 {'p', BOOLEAN, &orientation_doubt, &portrait, 0},
  165.                 {'l', BOOLEAN, &orientation_doubt, &landscape, 0},
  166.                 {'L', STRING, NULL, &plabel, 1},
  167.                 {'\0'}};
  168.  
  169. char buf[80];
  170. main()
  171. {    PARAM *pp;
  172.     int i;
  173.  
  174.     printf("about to read file...\n");
  175.  
  176.     config("TEST.CFG", ";d:\\bin/", parmv, buf, 80);
  177.  
  178.     printf("file read\n");
  179.  
  180.     for (pp = parmv; pp->flag; pp++)
  181.         {printf("%c: %10s\n", pp->flag, pp->ask[0]?"asking":"not asking");
  182.         for (i = 0; i < pp->nvar; i++)
  183.             switch(pp->type)
  184.                 {case REAL:    printf("\t\t%f\n", ((double *)pp->var)[i]); break;
  185.                 case BOOLEAN:    printf("\t\t%d\n", ((int *)pp->var)[i]); break;
  186.                 case STRING:    printf("\t\t%s\n", ((char **)pp->var)[i]); break;
  187.                 case CHARACTER:    printf("\t\t%c\n", ((char *)pp->var)[i]); break;
  188.                 }
  189.         }
  190.     printf("structure printed\n");
  191.     printf("portrait  = %d\n", portrait);
  192.     printf("landscape = %d\n", landscape);
  193. }
  194.  
  195.  
  196. #endif /* MAIN */
  197.