home *** CD-ROM | disk | FTP | other *** search
/ Black Box 4 / BlackBox.cdr / progc / snip1091.arj / INITVARS.C < prev    next >
C/C++ Source or Header  |  1991-09-11  |  5KB  |  138 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <stdarg.h>
  4. #include <string.h>
  5. #include <ctype.h>
  6. #include <assert.h>
  7.  
  8. /**** init_globals(fp, names, types, ...)
  9. **
  10. ** public domain by Raymond Gardner     Sept. 1991
  11. **
  12. ** fp is a FILE * to the (already fopen'ed) file containing
  13. **      initialization data
  14. **  names is a space-separated list of names of globals (as they
  15. **      are to appear in the data file)
  16. **  types is a list of datatype characters, corresponding to names
  17. **      i  for a pointer to integer
  18. **      s  for a pointer to string (already allocated char array)
  19. **      p  for a pointer to pointer to char (space will be malloc'd)
  20. **    (NOTE: no whitespace allowed in types !!)
  21. **  followed by var arg list of pointers to variables to init
  22. */
  23. #define LNSZ 256
  24. int init_globals(FILE *fp, char *names, char *types, ...)
  25. {
  26.     char ln[LNSZ];
  27.     char *p;
  28.     va_list arglist;
  29.     char *namep, *typep, name[40], *e;
  30.     void *argp;
  31.     int k;
  32.  
  33.     while ( fgets(ln, LNSZ, fp) ) {             /* read init file */
  34.         while ( isspace(ln[0]) )            /* drop leading whitespace */
  35.             memmove(ln, ln+1, strlen(ln));
  36.         if ( ln[0] == 0 )                       /* skip if blank line */
  37.             continue;
  38.         p = strchr(ln, '=');                    /* find equal sign */
  39.         if ( p == NULL )                        /* error if none */
  40.             return -1;  /* or continue; */
  41.         while ( p > ln && isspace(p[-1]) ) {    /* remove whitespace */
  42.             memmove(p-1, p, strlen(p-1));       /*   before = sign */
  43.             --p;
  44.         }
  45.         *p++ = 0;                               /* plug EOS over = sign */
  46.         while ( isspace(p[0]) )             /* remove leading space on */
  47.             memmove(p, p+1, strlen(p));         /*    init string */
  48.         k = strlen(p) - 1;                      /* init string length */
  49.         if ( k < 1 )
  50.             return -1;
  51.  
  52.         if ( p[k] != '\n' )             /* if '\n' is missing, input */
  53.             return -1;                  /*   exceeded buffer; error return */
  54.         p[k] = 0;                       /* plug EOS over newline */
  55.  
  56.         va_start(arglist, types);       /* setup for arglist search */
  57.  
  58.         namep = names;                  /* init ptr to var names */
  59.         typep = types;                  /* init ptr to var types */
  60.         while ( *namep == ' ' )         /* skip blanks before namelist */
  61.             ++namep;
  62.         while ( *typep ) {          /* while any typelist items left...*/
  63.  
  64.             argp = (void *)va_arg(arglist, void *); /* get var arg */
  65.  
  66.             k = strcspn(namep, " ");        /* length of namelist entry */
  67.             memmove(name, namep, k);        /* put into name hold area */
  68.             name[k] = 0;                    /* terminate it */
  69.             if ( strcmp(name, ln) != 0 ) { /* if it doesn't match... */
  70.                 namep += k;                 /* get next name */
  71.                 while ( *namep == ' ' )
  72.                     ++namep;
  73.                 ++typep;                    /* get next type */
  74.             } else {                        /* else name is found... */
  75.                 if ( *typep == 'i' ) {      /* if it's an int, init it */
  76.                     *(int *)argp = atoi(p);
  77.                 } else if ( *typep == 's' || *typep == 'p' ) {
  78.                     if ( *p == '"' ) {      /* is string in quotes? */
  79.                         ++p;                /* skip leading quote, and */
  80.                         e = strchr(p, '"'); /* look for trailing quote */
  81.                         if ( e )            /* terminate string if found */
  82.                             *e = 0;
  83.                     }
  84.                     if ( *typep == 'p' ) {      /* if it's a char *ptr */
  85.                         e = malloc(strlen(p) + 1); /* get space */
  86.                         if ( e == 0 ) {         /* error if no space */
  87.                             return -1; /* call va_end(arglist); first? */
  88.                         }
  89.                         *(char **)argp = e;
  90.                         strcpy(*(char **)argp, p);  /* copy in string */
  91.                     } else                          /* must be char array */
  92.                         strcpy(argp, p);            /* copy in string */
  93.                 } else {
  94.                     return -1;                      /* bad type */
  95.                 }
  96.                 break;              /* break search; get next line */
  97.             }
  98.         }
  99.         va_end(arglist);
  100.     }
  101.     return 0;
  102. }
  103. #ifdef TEST
  104.  
  105. int foo;
  106. char bar[80];
  107. int baz;
  108. char *quux;
  109.  
  110. int main(int argc, char **argv)
  111. {
  112.     FILE *fp;
  113.     int k;
  114.  
  115.     if ( argc < 2 ) {
  116.         fprintf(stderr, "missing arg\n");
  117.         exit(1);
  118.     }
  119.  
  120.     fp = fopen(argv[1], "r");
  121.     assert(fp);
  122.     k = init_globals(fp, "foo bar baz quux", "isip",
  123.         &foo, bar, &baz, &quux);
  124.     printf("k: %d\n", k);
  125.     printf("foo: %d\nbar: <%s>\nbaz: %d\nquux: <%s>\n",
  126.         foo, bar, baz, quux);
  127.     fclose(fp);
  128.  
  129.     return 0;
  130. }
  131. #endif
  132. /* test data file:
  133. foo=123
  134. bar = "a test"
  135.    baz     =  456
  136. quux=    what is this
  137. */
  138.