(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:
parent
4798d1466b
commit
d89c268b8b
6 changed files with 282 additions and 319 deletions
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue