nsc: Rename nstr_exec_val() to nstr_eval() and tighten contract
nstr_exec_val() can produce three different error values: NSC_NOTYPE on invalid category, invalid type with zero val_as.lng on invalid type (this is a bug), and the wanted type with zero val_s when it can't coerce. None of these should ever happen. Fix it to always produce an NSC_NOTYPE error value. Fix up callers to check for it. Specify the result's type is promoted on success. Ensure it is even when the argument is NSC_VAL with an unpromoted type, which is invalid. Signed-off-by: Markus Armbruster <armbru@pond.sub.org>
This commit is contained in:
parent
5a1544f925
commit
143a4e4e6f
6 changed files with 29 additions and 20 deletions
|
@ -286,7 +286,7 @@ extern struct symbol sector_navigation[];
|
|||
|
||||
/* src/lib/common/nstreval.c */
|
||||
extern struct valstr *nstr_mksymval(struct valstr *, struct castr *, int);
|
||||
extern struct valstr *nstr_exec_val(struct valstr *, natid, void *,
|
||||
extern struct valstr *nstr_eval(struct valstr *, natid, void *,
|
||||
enum nsc_type);
|
||||
extern int nstr_promote(int);
|
||||
extern char *symbol_by_value(int, struct symbol *);
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
*
|
||||
* Known contributors to this file:
|
||||
* Dave Pare, 1986
|
||||
* Markus Armbruster, 2004-2014
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@ -135,7 +136,9 @@ code_char(struct valstr val, struct sctstr *sp)
|
|||
int n;
|
||||
int large = val.val_type != NSC_CHAR && val.val_type != NSC_UCHAR;
|
||||
|
||||
nstr_exec_val(&val, player->cnum, sp, NSC_LONG);
|
||||
nstr_eval(&val, player->cnum, sp, NSC_LONG);
|
||||
if (CANT_HAPPEN(val.val_type != NSC_LONG))
|
||||
return ' ';
|
||||
amt = val.val_as.lng;
|
||||
if (amt <= 0)
|
||||
return ' ';
|
||||
|
|
|
@ -169,7 +169,7 @@ verify_row(int type, int row)
|
|||
if (ca[i].ca_table == EF_BAD)
|
||||
continue;
|
||||
nstr_mksymval(&val, &ca[i], j);
|
||||
nstr_exec_val(&val, 0, row_ref, NSC_NOTYPE);
|
||||
nstr_eval(&val, 0, row_ref, NSC_NOTYPE);
|
||||
if (CANT_HAPPEN(val.val_type != NSC_LONG)) {
|
||||
ret_val = -1;
|
||||
continue;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 1997
|
||||
* Markus Armbruster, 2004-2008
|
||||
* Markus Armbruster, 2004-2014
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@ -59,16 +59,19 @@ nstr_mksymval(struct valstr *val, struct castr *ca, int idx)
|
|||
|
||||
/*
|
||||
* Evaluate VAL.
|
||||
* If VAL is symbolic, evaluate it into a promoted value type.
|
||||
* Translate it for country CNUM (coordinate system and contact
|
||||
* status), except when CNUM is NATID_BAD.
|
||||
* If VAL has category NSC_OFF, read the value from the context object
|
||||
* PTR, and translate it for country CNUM (coordinate system and
|
||||
* contact status). No translation when CNUM is NATID_BAD.
|
||||
* PTR points to a context object of the type that was used to compile
|
||||
* the value.
|
||||
* Unless WANT is NSC_NOTYPE, coerce the value to promoted value type
|
||||
* WANT. VAL must be coercible.
|
||||
* The result's type is promoted on success, NSC_NOTYPE on error.
|
||||
* In either case, the category is NSC_VAL.
|
||||
* Return VAL.
|
||||
*/
|
||||
struct valstr *
|
||||
nstr_exec_val(struct valstr *val, natid cnum, void *ptr, enum nsc_type want)
|
||||
nstr_eval(struct valstr *val, natid cnum, void *ptr, enum nsc_type want)
|
||||
{
|
||||
char *memb_ptr;
|
||||
enum nsc_type valtype;
|
||||
|
@ -82,6 +85,8 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, enum nsc_type want)
|
|||
switch (val->val_cat) {
|
||||
case NSC_VAL:
|
||||
valtype = val->val_type;
|
||||
if (CANT_HAPPEN(!NSC_IS_PROMOTED(valtype)))
|
||||
valtype = nstr_promote(valtype);
|
||||
break;
|
||||
case NSC_OFF:
|
||||
if (val->val_as.sym.get) {
|
||||
|
@ -168,6 +173,7 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, enum nsc_type want)
|
|||
case NSC_STRING:
|
||||
val->val_as.str.base = ((char **)memb_ptr)[idx];
|
||||
val->val_as.str.maxsz = INT_MAX;
|
||||
/* really SIZE_MAX, but that's C99 */
|
||||
valtype = NSC_STRING;
|
||||
break;
|
||||
case NSC_TIME:
|
||||
|
@ -175,7 +181,7 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, enum nsc_type want)
|
|||
break;
|
||||
default:
|
||||
CANT_REACH();
|
||||
val->val_as.lng = 0;
|
||||
valtype = NSC_NOTYPE;
|
||||
}
|
||||
val->val_cat = NSC_VAL;
|
||||
break;
|
||||
|
@ -194,11 +200,8 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, enum nsc_type want)
|
|||
}
|
||||
}
|
||||
|
||||
if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
|
||||
/* make up an error value */
|
||||
valtype = want;
|
||||
memset(&val->val_as, 0, sizeof(val->val_as));
|
||||
}
|
||||
if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE))
|
||||
valtype = NSC_NOTYPE;
|
||||
|
||||
val->val_type = valtype;
|
||||
return val;
|
||||
|
|
|
@ -112,7 +112,7 @@ xdeval(struct valstr *val, struct xdstr *xd,
|
|||
struct castr *ca, void *ptr, int idx)
|
||||
{
|
||||
nstr_mksymval(val, ca, idx);
|
||||
return nstr_exec_val(val, xd->cnum, ptr, NSC_NOTYPE);
|
||||
return nstr_eval(val, xd->cnum, ptr, NSC_NOTYPE);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
* Known contributors to this file:
|
||||
* Dave Pare, 1989
|
||||
* Steve McClure, 1997
|
||||
* Markus Armbruster, 2004-2013
|
||||
* Markus Armbruster, 2004-2014
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
@ -231,7 +231,8 @@ strnncmp(char *s1, size_t sz1, char *s2, size_t sz2)
|
|||
int
|
||||
nstr_exec(struct nscstr *np, int ncond, void *ptr)
|
||||
{
|
||||
int i, op, optype, cmp;
|
||||
int i, op, cmp;
|
||||
enum nsc_type optype;
|
||||
struct valstr lft, rgt;
|
||||
|
||||
for (i = 0; i < ncond; ++i) {
|
||||
|
@ -240,9 +241,11 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr)
|
|||
if (np[i].lft.val_cat == NSC_NOCAT || np[i].rgt.val_cat == NSC_NOCAT)
|
||||
return 0;
|
||||
lft = np[i].lft;
|
||||
nstr_exec_val(&lft, player->cnum, ptr, optype);
|
||||
nstr_eval(&lft, player->cnum, ptr, optype);
|
||||
rgt = np[i].rgt;
|
||||
nstr_exec_val(&rgt, player->cnum, ptr, optype);
|
||||
nstr_eval(&rgt, player->cnum, ptr, optype);
|
||||
if (CANT_HAPPEN(lft.val_type != optype || rgt.val_type != optype))
|
||||
return 0;
|
||||
switch (optype) {
|
||||
case NSC_LONG:
|
||||
if (!EVAL(op, lft.val_as.lng, rgt.val_as.lng))
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue