gnuboy-for-dfi/rcvars.c

236 lines
3.1 KiB
C

#undef _GNU_SOURCE
#define _GNU_SOURCE
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "defs.h"
#include "rc.h"
static rcvar_t *rcvars;
static int nvars;
void rc_export(rcvar_t *v)
{
const rcvar_t end = RCV_END;
if (!v) return;
nvars++;
rcvars = realloc(rcvars, sizeof (rcvar_t) * (nvars+1));
if (!rcvars)
die("out of memory adding rcvar %s\n", v->name);
rcvars[nvars-1] = *v;
rcvars[nvars] = end;
}
void rc_exportvars(rcvar_t *vars)
{
while(vars->type)
rc_export(vars++);
}
int rc_findvar(char *name)
{
int i;
if (!rcvars) return -1;
for (i = 0; rcvars[i].name; i++)
if (!strcmp(rcvars[i].name, name))
break;
if (!rcvars[i].name)
return -1;
return i;
}
int my_atoi(const char *s)
{
int a = 0;
if (*s == '0')
{
s++;
if (*s == 'x' || *s == 'X')
{
s++;
while (*s)
{
if (isdigit(*s))
a = (a<<4) + *s - '0';
else if (strchr("ABCDEF", *s))
a = (a<<4) + *s - 'A' + 10;
else if (strchr("abcdef", *s))
a = (a<<4) + *s - 'a' + 10;
else return a;
s++;
}
return a;
}
while (*s)
{
if (strchr("01234567", *s))
a = (a<<3) + *s - '0';
else return a;
s++;
}
return a;
}
if (*s == '-')
{
s++;
for (;;)
{
if (isdigit(*s))
a = (a*10) + *s - '0';
else return -a;
s++;
}
}
while (*s)
{
if (isdigit(*s))
a = (a*10) + *s - '0';
else return a;
s++;
}
return a;
}
int rc_setvar_n(int i, int c, char **v)
{
int j;
int *n;
char **s;
switch (rcvars[i].type)
{
case rcv_int:
if (c < 1) return -1;
n = (int *)rcvars[i].mem;
*n = my_atoi(v[0]);
return 0;
case rcv_string:
if (c < 1) return -1;
s = (char **)rcvars[i].mem;
if (*s) free(*s);
*s = strdup(v[0]);
if (!*s)
die("out of memory setting rcvar %s\n", rcvars[i].name);
return 0;
case rcv_vector:
if (c > rcvars[i].len)
c = rcvars[i].len;
for (j = 0; j < c ; j++)
((int *)rcvars[i].mem)[j] = my_atoi(v[j]);
return 0;
case rcv_bool:
if (c < 1 || atoi(v[0]) || strchr("yYtT", v[0][0]))
*(int *)rcvars[i].mem = 1;
else if (strchr("0nNfF", v[0][0]))
*(int *)rcvars[i].mem = 0;
else
return -1;
return 0;
}
return -1;
}
int rc_setvar(char *name, int c, char **v)
{
int i;
i = rc_findvar(name);
if (i < 0) return i;
return rc_setvar_n(i, c, v);
}
void *rc_getmem_n(int i)
{
return rcvars[i].mem;
}
void *rc_getmem(char *name)
{
int i;
i = rc_findvar(name);
if (i < 0) return NULL;
return rcvars[i].mem;
}
int rc_getint_n(int i)
{
if (i < 0) return 0;
switch (rcvars[i].type)
{
case rcv_int:
case rcv_bool:
return *(int *)rcvars[i].mem;
}
return 0;
}
int *rc_getvec_n(int i)
{
if (i < 0) return NULL;
switch (rcvars[i].type)
{
case rcv_int:
case rcv_bool:
case rcv_vector:
return (int *)rcvars[i].mem;
}
return NULL;
}
char *rc_getstr_n(int i)
{
if (i < 0) return 0;
switch (rcvars[i].type)
{
case rcv_string:
return *(char **)rcvars[i].mem;
}
return 0;
}
int rc_getint(char *name)
{
return rc_getint_n(rc_findvar(name));
}
int *rc_getvec(char *name)
{
return rc_getvec_n(rc_findvar(name));
}
char *rc_getstr(char *name)
{
return rc_getstr_n(rc_findvar(name));
}