]> git.pond.sub.org Git - empserver/commitdiff
nsc: Rename nstr_exec_val() to nstr_eval() and tighten contract
authorMarkus Armbruster <armbru@pond.sub.org>
Sun, 2 Feb 2014 08:39:35 +0000 (09:39 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Sun, 1 Feb 2015 15:52:59 +0000 (16:52 +0100)
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>
include/nsc.h
src/lib/commands/surv.c
src/lib/common/ef_verify.c
src/lib/common/nstreval.c
src/lib/common/xdump.c
src/lib/subs/nstr.c

index 3b7fc35fe5e8c58cd92a8ed727d7b35d6272c3f4..e2b4b33c7a17b41c418eac20a70c7c8f111d5edb 100644 (file)
@@ -286,8 +286,8 @@ 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 *,
-                                   enum nsc_type);
+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 *);
 /* src/lib/global/nsc.c */
index c5a5987a7464973e83ed3eac64d1b031bbb1b559..1be364c3b18d00a6253d7fe005d9dc62cc88f495 100644 (file)
@@ -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 ' ';
index bc675f4ef4d9e07300b4c0a23738a189919a268a..17057c598589aafbb3e2082d3e5b2467b4017516 100644 (file)
@@ -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;
index 074dfd1f1753650bb42ca9d2be2a96e0ed2eeb81..1d7f2b3893b51b3ffa38e5ff86428ef148580a6c 100644 (file)
@@ -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;
index 0809d084c78240104a4b2852007536c32b90469b..ff1ee6deb1616931eab55fc042979f8cea80d8d5 100644 (file)
@@ -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);
 }
 
 /*
index eca8f7c463f63b0ea62b85e48cdc8df3216049d7..f9987e78ccb703d6394720c810f732a26544bec1 100644 (file)
@@ -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))