(keymatch): Replace member km_func by km_type. Initializers adapted.

(emp_config, print_config): Cope with km_type.
(worldxset, intset, floatset, optstrset, doubleset, longset): Unused,
remove.

(emp_config): Fail if specified file can't be read or contains errors.
Used to succeed always, returning RET_OK.  RET_OK is not appropriate,
since this is not a command.  Return 0 on success, -1 on failure.
Callers ignore failure at the moment.  A missing or unreadable econfig
file used to be silently ignored.  It is still ignored, but no longer
silently.  It is questionable whether ignoring is wise, but that's
left for another day.

(emp_config): Improve diagnostic messages.

(set_option): Move diagnostics to caller.

(emp_config): Ignore leading whitespace in `#' comment lines.

(print_config): Simplify printing of km_comment.

(set_option): New parameter val, so it can set and clear options.
(delete_option): Remove.

(KM_ALLOC): Turn macro into enumeration constant.

(KM_INTERNAL): New.
(xdump, xdver): New version dump.

(keymatch, infodir, datadir, teldir, upfil, downfil, disablefil,
telfil, annfil, banfil, timestampfil, privname, privlog, update_times,
update_demandtimes, game_days, game_hours): Use plain char * instead
of s_char * for strings, void * for generic pointers.
This commit is contained in:
Markus Armbruster 2004-09-04 08:07:51 +00:00
parent 4798d1466b
commit d89c268b8b
6 changed files with 282 additions and 319 deletions

View file

@ -43,6 +43,8 @@
*
*/
#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h> /* atoi free atol */
#include <string.h>
@ -63,15 +65,6 @@ extern char *strdup();
/* Dummy one */
static int emp_config_dummy;
static void optstrset(struct keymatch *kp, s_char **av);
static void intset(struct keymatch *kp, s_char **av);
static void floatset(struct keymatch *kp, s_char **av);
static void doubleset(struct keymatch *kp, s_char **av);
static void longset(struct keymatch *kp, s_char **av);
static void optionset(struct keymatch *kp, s_char **av);
static void optiondel(struct keymatch *kp, s_char **av);
static void worldxset(struct keymatch *kp, s_char **av);
/* things that can be changed */
struct keymatch configkeys[] = {
#define EMP_CONFIG_C_OUTPUT
@ -81,7 +74,7 @@ struct keymatch configkeys[] = {
static void fixup_files(void);
static struct keymatch *keylookup(s_char *key, struct keymatch tbl[]);
static int set_option(const char *, int);
/*
* read in empire configuration
@ -90,36 +83,93 @@ int
emp_config(char *file)
{
FILE *fp;
s_char scanspace[1024];
s_char *av[65];
char scanspace[1024];
char *av[65];
char buf[BUFSIZ];
struct keymatch *kp;
int lno = 0;
int errors = 0;
int i;
if (file == NULL || (fp = fopen(file, "r")) == NULL) {
if (file == NULL) {
fixup_files();
return RET_OK;
return 0;
}
if ((fp = fopen(file, "r")) == NULL) {
fprintf(stderr, "Can't open %s for reading (%s)\n",
file, strerror(errno));
return -1;
}
while (fgets(buf, sizeof buf, fp) != NULL) {
if (buf[0] == '#' || buf[0] == '\n')
++lno;
for (i = 0; buf[i] && isspace(buf[i]); ++i) ;
if (!buf[i] || buf[i] == '#')
continue;
if (parse(buf, av, 0, scanspace, 0) < 0) {
fprintf(stderr, "Can't parse line %s", buf);
fprintf(stderr, "%s:%d: Can't parse line %s", file, lno, buf);
errors = 1;
continue;
}
if ((kp = keylookup(av[0], configkeys)) != NULL) {
(*kp->km_func) (kp, av + 1);
} else {
fprintf(stderr, "Unknown config key %s\n", av[0]);
if ((kp = keylookup(av[0], configkeys)) == NULL) {
fprintf(stderr, "%s:%d: Unknown config key %s\n",
file, lno, av[0]);
errors = 1;
continue;
}
if (av[1] == NULL) {
fprintf(stderr, "%s:%d: Config key %s needs a value\n",
file, lno, av[0]);
errors = 1;
continue;
}
i = 2;
switch (kp->km_type) {
case NSC_INT:
*(int *)kp->km_data = atoi(av[1]);
break;
case NSC_FLOAT:
*(float *)kp->km_data = atof(av[1]);
break;
case NSC_DOUBLE:
*(double *)kp->km_data = atof(av[1]);
break;
case NSC_LONG:
*(long *)kp->km_data = atol(av[1]);
break;
case NSC_STRING:
if (kp->km_flags & KM_ALLOC)
free(*(char **)kp->km_data);
*(char **)kp->km_data = strdup(av[1]);
kp->km_flags |= KM_ALLOC;
break;
case NSC_NOTYPE:
for (i = 1; av[i]; ++i) {
if (set_option(av[i], kp->km_key[0] != 'n') < 0) {
fprintf(stderr, "%s:%d: Unknown option %s\n",
file, lno, av[i]);
errors = 1;
}
}
break;
default:
assert(0);
}
if (av[i] != NULL) {
fprintf(stderr, "%s:%d: Junk after value of config key %s\n",
file, lno, av[0]);
errors = 1;
}
}
fclose(fp);
fixup_files();
WORLD_X &= ~1; /* make even */
return RET_OK;
return -errors;
}
struct otherfiles {
s_char **files;
char **files;
char *name;
};
@ -184,188 +234,66 @@ keylookup(register s_char *command, struct keymatch *tbl)
return NULL;
}
/* worldx int setting function */
static void
worldxset(struct keymatch *kp, s_char **av)
{
int *intptr = (int *)kp->km_data;
if (*av == NULL || intptr == NULL)
return;
*intptr = atoi(*av);
if (!((*intptr % 2) == 0)) {
/* Must be div / 2, so subtract one */
*intptr = *intptr - 1;
}
}
/* generic int setting function */
static void
intset(struct keymatch *kp, s_char **av)
{
int *intptr = (int *)kp->km_data;
if (*av == NULL || intptr == NULL)
return;
*intptr = atoi(*av);
}
/* generic float set function */
static void
floatset(struct keymatch *kp, s_char **av)
{
float *floatptr = (float *)kp->km_data;
if (*av == NULL || floatptr == NULL)
return;
*floatptr = atof(*av);
}
/* generic string set function */
static void
optstrset(struct keymatch *kp, s_char **av)
{
s_char **confstrp = (s_char **)kp->km_data;
if (*av == NULL || confstrp == NULL)
return;
if (kp->km_flags & KM_ALLOC)
free(*confstrp);
*confstrp = strdup(*av);
kp->km_flags |= KM_ALLOC;
}
/* generic double set function */
static void
doubleset(struct keymatch *kp, s_char **av)
{
double *doublep = (double *)kp->km_data;
if (*av == NULL || doublep == NULL)
return;
*doublep = atof(*av);
}
/* generic long set function */
static void
longset(struct keymatch *kp, s_char **av)
{
long int *longp = (long int *)kp->km_data;
if (*av == NULL || longp == NULL)
return;
*longp = atol(*av);
}
void
print_config(FILE * fp)
print_config(FILE *fp)
{
struct empfile *ep;
struct otherfiles *op;
struct option_list *op;
struct otherfiles *ofp;
struct keymatch *kp;
fprintf(fp, "# Empire Configuration File:\n");
for (kp = configkeys; kp->km_key; kp++) {
/* We print a few special things here */
if (kp->km_comment) {
if (kp->km_comment[0]) {
if (kp->km_comment[0] != '\n')
fprintf(fp, "\n# ");
fprintf(fp, "%s\n", kp->km_comment);
}
}
if (kp->km_comment)
fprintf(fp, "\n# %s\n", kp->km_comment);
if (!kp->km_key[0])
continue;
if (kp->km_func == optstrset) {
fprintf(fp, "%s \"%s\"\n", kp->km_key,
*(s_char **)kp->km_data);
} else if (kp->km_func == intset) {
switch (kp->km_type) {
case NSC_STRING:
fprintf(fp, "%s \"%s\"\n", kp->km_key, *(char **)kp->km_data);
break;
case NSC_INT:
fprintf(fp, "%s %d\n", kp->km_key, *(int *)kp->km_data);
} else if (kp->km_func == worldxset) {
fprintf(fp, "%s %d\n", kp->km_key, *(int *)kp->km_data);
} else if (kp->km_func == floatset) {
break;
case NSC_FLOAT:
fprintf(fp, "%s %g\n", kp->km_key, *(float *)kp->km_data);
} else if (kp->km_func == doubleset) {
break;
case NSC_DOUBLE:
fprintf(fp, "%s %g\n", kp->km_key, *(double *)kp->km_data);
} else if (kp->km_func == longset) {
break;
case NSC_LONG:
fprintf(fp, "%s %ld\n", kp->km_key, *(long *)kp->km_data);
} else if (kp->km_func == optionset) {
struct option_list *op;
for (op = Options; op->opt_key; op++) {
if (*op->opt_valuep)
break;
case NSC_NOTYPE:
for (op = Options; op->opt_key; op++)
if (*op->opt_valuep != (kp->km_key[0] == 'n'))
fprintf(fp, "%s %s\n", kp->km_key, op->opt_key);
}
} else if (kp->km_func == optiondel) {
struct option_list *op;
for (op = Options; op->opt_key; op++) {
if (*op->opt_valuep == 0)
fprintf(fp, "%s %s\n", kp->km_key, op->opt_key);
}
} else
fprintf(fp, "# Unknown format %s\n", kp->km_key);
break;
default:
assert(0);
}
}
fprintf(fp, "\n");
for (ep = empfile; ep < &empfile[EF_MAX]; ep++)
fprintf(fp, "# File %s -> %s\n", ep->name, ep->file);
for (op = ofiles; op->files; op++)
fprintf(fp, "# File %s -> %s\n", op->name, *(op->files));
for (ofp = ofiles; ofp->files; ofp++)
fprintf(fp, "# File %s -> %s\n", ofp->name, *(ofp->files));
}
/* add an option to the list */
static void
set_option(const char *s)
/* Set option S to value VAL; return 0 on success, -1 on failure. */
static int
set_option(const char *s, int val)
{
struct option_list *op;
for (op = Options; op->opt_key; op++) {
if (strcmp(op->opt_key, s) == 0) {
*op->opt_valuep = 1;
return;
*op->opt_valuep = val;
return 0;
}
}
fprintf(stderr, "Unknown option %s\n", s);
}
/* delete an option from the list */
static void
delete_option(const char *s)
{
struct option_list *op;
for (op = Options; op->opt_key; op++) {
if (strcmp(op->opt_key, s) == 0) {
*op->opt_valuep = 0;
return;
}
}
fprintf(stderr, "Unknown option %s\n", s);
}
/* config interface */
static void
optionset(struct keymatch *kp, s_char **av)
/* unused - we have a well known global */
{
char **cpp;
for (cpp = (char **)av; *cpp; cpp++)
set_option(*cpp);
}
/* config interface */
static void
optiondel(struct keymatch *kp, s_char **av)
/* unused - we have a well known global */
{
char **cpp;
for (cpp = (char **)av; *cpp; cpp++)
delete_option(*cpp);
return -1;
}