Virtual selectors

Where ordinary selectors specify a value stored in some object,
virtual selectors specify a function to call to compute a value
associated with some object.

Use them to replace the special case xdump ver by new table
EF_VERSION.

Move configkeys[] to lib/common because nsc_init() needs it to
initialize empfile[EF_VERSION].cadef.
This commit is contained in:
Markus Armbruster 2008-03-04 21:02:00 +01:00
parent 38047a62f7
commit da8a1daeef
12 changed files with 541 additions and 482 deletions

View file

@ -87,21 +87,19 @@
/*
* Evaluate a attribute of an object into VAL, return VAL.
* TYPE is the attribute's type.
* CA describes the attribute.
* PTR points to the context object.
* The attribute is stored there at offset OFF + IDX * S, where S is
* its size.
* LEN is the #array elements if it is an array, else zero.
* IDX is the index within the attribute.
*/
static struct valstr *
xdeval(struct valstr *val,
nsc_type type, void *ptr, ptrdiff_t off, int idx, int len)
xdeval(struct valstr *val, struct castr *ca, void *ptr, int idx)
{
val->val_type = type;
val->val_type = ca->ca_type;
val->val_cat = NSC_OFF;
val->val_as.sym.off = off;
val->val_as.sym.len = len;
val->val_as.sym.off = ca->ca_off;
val->val_as.sym.len = ca->ca_len;
val->val_as.sym.idx = idx;
val->val_as.sym.get = ca->ca_get;
return nstr_exec_val(val, player->cnum, ptr, NSC_NOTYPE);
}
@ -175,7 +173,7 @@ xdflds(struct castr ca[], void *ptr)
n = ca[i].ca_type != NSC_STRINGY ? ca[i].ca_len : 0;
j = 0;
do {
xdeval(&val, ca[i].ca_type, ptr, ca[i].ca_off, j, ca[i].ca_len);
xdeval(&val, &ca[i], ptr, j);
sep = xdprval(&val, sep);
} while (++j < n);
}
@ -337,62 +335,7 @@ xdmeta(int type)
return RET_OK;
}
/*
* Dump configkeys[], return RET_OK.
* If META, dump meta-data rather than data.
*/
static int
xdver(int meta)
{
static struct castr vers_ca = {
"version", 0, NSC_STRINGY, sizeof(PACKAGE_STRING), EF_BAD, 0
};
struct keymatch *kp;
char *sep;
int n;
struct castr ca;
struct valstr val;
xdhdr("version", meta);
if (meta) {
n = 0;
xdflds(mdchr_ca, &vers_ca);
pr("\n");
n++;
for (kp = configkeys; kp->km_key; ++kp) {
if (kp->km_type != NSC_NOTYPE && !(kp->km_flags & KM_INTERNAL)) {
ca.ca_type = kp->km_type;
ca.ca_flags = 0;
ca.ca_len = 0;
ca.ca_off = 0;
ca.ca_name = kp->km_key;
ca.ca_table = EF_BAD;
xdflds(mdchr_ca, &ca);
pr("\n");
n++;
}
}
xdftr(n);
return RET_OK;
}
xdeval(&val, vers_ca.ca_type, version, vers_ca.ca_off, 0, vers_ca.ca_len);
sep = xdprval(&val, "");
for (kp = configkeys; kp->km_key; ++kp) {
if (kp->km_type != NSC_NOTYPE && !(kp->km_flags & KM_INTERNAL)) {
xdeval(&val, kp->km_type, kp->km_data, 0, 0, 0);
sep = xdprval(&val, sep);
}
}
pr("\n");
xdftr(1);
return RET_OK;
}
/* Experimental extended dump command */
/* Extended dump command */
int
xdump(void)
{
@ -412,18 +355,17 @@ xdump(void)
natp = getnatp(player->cnum);
type = isdigit(p[0]) ? atoi(p) : ef_byname(p);
if (type >= 0 && type < EF_MAX) {
if (meta)
return xdmeta(type);
else if ((EF_IS_GAME_STATE(type) || EF_IS_VIEW(type))
&& !(natp->nat_stat == STAT_ACTIVE || player->god)) {
pr("Access to table %s denied\n", ef_nameof(type));
return RET_FAIL;
} else
return xditem(type, player->argp[2]);
} else if (!strncmp(p, "ver", strlen(p))) {
return xdver(meta);
}
if (type < 0 || type >= EF_MAX)
return RET_SYN;
return RET_SYN;
if (meta)
return xdmeta(type);
if ((EF_IS_GAME_STATE(type) || EF_IS_VIEW(type))
&& !(natp->nat_stat == STAT_ACTIVE || player->god)) {
pr("Access to table %s denied\n", ef_nameof(type));
return RET_FAIL;
}
if (type == EF_VERSION && !player->argp[2])
return xditem(type, "*"); /* backward compatibility */
return xditem(type, player->argp[2]);
}

View file

@ -107,6 +107,7 @@ verify_row(int type, int row)
val.val_as.sym.off = ca[i].ca_off;
val.val_as.sym.len = ca[i].ca_len;
val.val_as.sym.idx = j;
val.val_as.sym.get = ca[i].ca_get;
nstr_exec_val(&val, 0, row_ref, NSC_NOTYPE);
if (val.val_type != NSC_LONG)
continue;

View file

@ -55,16 +55,6 @@
#include "optlist.h"
#include "prototypes.h"
/* Dummy one */
static int emp_config_dummy;
/* things that can be changed */
struct keymatch configkeys[] = {
#define EMP_CONFIG_C_OUTPUT
#include "econfig-spec.h"
#undef EMP_CONFIG_C_OUTPUT
};
static struct keymatch *keylookup(char *key, struct keymatch tbl[]);
static int set_paths(char *);

View file

@ -69,6 +69,17 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
valtype = val->val_type;
break;
case NSC_OFF:
if (val->val_as.sym.get) {
do {
ptr = val->val_as.sym.get(val, cnum, ptr);
} while (ptr && val->val_as.sym.get);
if (!ptr) {
valtype = val->val_type;
val->val_cat = NSC_VAL;
break;
}
}
valtype = NSC_LONG;
memb_ptr = ptr;
memb_ptr += val->val_as.sym.off;

View file

@ -221,3 +221,11 @@ float start_education = 0.0;
float start_happiness = 0.0;
float start_technology = 0.0;
float start_research = 0.0;
/* econfig keys */
static int emp_config_dummy;
struct keymatch configkeys[] = {
#define EMP_CONFIG_C_OUTPUT
#include "econfig-spec.h"
#undef EMP_CONFIG_C_OUTPUT
};

View file

@ -53,6 +53,7 @@
#include "server.h"
#include "trade.h"
#include "treaty.h"
#include "version.h"
#include "xy.h"
/* Number of elements in ARRAY. */
@ -102,7 +103,8 @@ struct empfile empfile[] = {
* that can be changed by users.
*
* Whatever of the above can't be done here must be done in
* empfile_init() or empfile_fixup().
* empfile_init() or empfile_fixup(). Except cadef may be set in
* nsc_init() instead.
*/
/*
@ -187,10 +189,13 @@ struct empfile empfile[] = {
ARRAY_TABLE(update_time, EFF_CFG)},
/*
* Special tables. EF_META gets bogus size, cids and fids here.
* Fixed up by empfile_init().
* Fixed up by empfile_init(). EF_VERSION's cadef is set by
* nsc_init().
*/
{EF_TABLE, "table", NULL, empfile_ca,
ARRAY_TABLE(empfile, EFF_CFG)},
{EF_VERSION, "version", NULL, NULL,
sizeof(PACKAGE_STRING), 0, version, 0, 0, 1, 1, -1, NULL, NULL},
{EF_META, "meta", NULL, mdchr_ca,
PTR_CACHE(mdchr_ca, EFF_CFG)},

File diff suppressed because it is too large Load diff

View file

@ -432,6 +432,7 @@ nstr_resolve_sel(struct valstr *val, struct castr *ca)
val->val_as.sym.off = ca->ca_off;
val->val_as.sym.len = ca->ca_len;
val->val_as.sym.idx = 0;
val->val_as.sym.get = ca->ca_get;
return val;
}