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