]> git.pond.sub.org Git - empserver/commitdiff
(valstr, nstr_exec, nstr_comp_val, nstr_exec_val, xdprval): Support
authorMarkus Armbruster <armbru@pond.sub.org>
Sat, 11 Sep 2004 08:45:17 +0000 (08:45 +0000)
committerMarkus Armbruster <armbru@pond.sub.org>
Sat, 11 Sep 2004 08:45:17 +0000 (08:45 +0000)
strings with length limit instead of zero termination.
(ship_ca, land_ca): New selectors rflags, rpath.  The latter is such a
string.

include/nsc.h
src/lib/commands/xdump.c
src/lib/global/nsc.c
src/lib/subs/nstr.c

index d2f022af733dc8f7e7dbc65a463ee9fc1613bb5c..545f23d743a6c6503b8fea8bb3b1b082227eb3ef 100644 (file)
@@ -97,11 +97,15 @@ struct valstr {
     union {
        struct {                /* cat NSC_OFF */
            ptrdiff_t off;
+           int len;
            int idx;
        } sym;
        double dbl;             /* cat NSC_VAL, type NSC_DOUBLE */
-       char *str;              /* cat NSC_VAL, type NSC_STRING */
-       long lng;               /* cat NSC_VAL, type NSC_LONG */
+       struct {                /* cat NSC_VAL, type NSC_STRING */
+           char *base;
+           size_t maxsz;
+       } str;
+       long lng;               /* cat NSC_VAL, type NSC_LONG, NSC_TYPEID */
     } val_as;
 };
 
index e9fe6103f56e5a2adb2a431c88ac08e85a8ef5cb..94f31aae957d58216eaae62485a8fe5675ebc2a6 100644 (file)
@@ -294,7 +294,7 @@ xdeval(struct valstr *val, nsc_type type, void *ptr, ptrdiff_t off, int idx)
 static char *
 xdprval(struct valstr *val, char *sep)
 {
-    unsigned char *s, *e;
+    unsigned char *s, *e, *l;
 
     switch (val->val_type) {
     case NSC_TYPEID:
@@ -305,14 +305,17 @@ xdprval(struct valstr *val, char *sep)
        pr("%s%#g", sep, val->val_as.dbl);
        break;
     case NSC_STRING:
-       s = (unsigned char *)val->val_as.str;
+       s = (unsigned char *)val->val_as.str.base;
        if (s) {
            pr("%s\"", sep);
-           while (*s) {
-               for (e = s; *e != '"' && *e != '\\' && isgraph(*e); ++e) ;
+           l = s + val->val_as.str.maxsz;
+           for (;;) {
+               for (e=s; e<l && *e != '"' && *e != '\\' && isgraph(*e); ++e) ;
                pr("%.*s", (int)(e-s), s);
-               if (*e)
+               if (e < l && *e)
                    pr("\\%03o", *e++);
+               else
+                   break;
                s = e;
            }
            prnf("\"");
@@ -455,7 +458,7 @@ xdchr(int chridx)
        val.val_as.sym.off = cm->ca[0].ca_off;
        val.val_as.sym.idx = 0;
        nstr_exec_val(&val, player->cnum, p, NSC_STRING);
-       if (!val.val_as.str || !*val.val_as.str)
+       if (!val.val_as.str.base || !*val.val_as.str.base)
            break;
        ++n;
        xdflds(cm->ca, p);
index ea23f1a6822a8132e8c572afd2e08cdfa03d4c5c..c8f151ddc73938c193c544aaf6c50ebb83ec07a8 100644 (file)
@@ -153,7 +153,8 @@ struct castr ship_ca[] = {
     {NSC_XCOORD, NSC_DEITY, 0, fldoff(shpstr, shp_orig_x), "xbuilt"},
     {NSC_YCOORD, NSC_DEITY, 0, fldoff(shpstr, shp_orig_y), "ybuilt"},
     {NSC_NATID, NSC_DEITY, 0, fldoff(shpstr, shp_orig_own), "builder"},
-    /* FIXME retreat stuff missing */
+    {NSC_INT, 0, 0, fldoff(shpstr, shp_rflags), "rflags"},
+    {NSC_STRINGY, 0, RET_LEN, fldoff(shpstr, shp_rpath), "rpath"},
     {NSC_NOTYPE, 0, 0, 0, NULL}
 };
 
@@ -182,7 +183,8 @@ struct castr land_ca[] = {
     {NSC_SHORT, 0, 0, fldoff(lndstr, lnd_retreat), "retreat"},
     {NSC_UCHAR, 0, 0, fldoff(lndstr, lnd_fuel), "fuel"},
     {NSC_UCHAR, 0, 0, fldoff(lndstr, lnd_nxlight), "nxlight"},
-    /* FIXME retreat stuff missing */
+    {NSC_INT, 0, 0, fldoff(lndstr, lnd_rflags), "rflags"},
+    {NSC_STRINGY, 0, RET_LEN, fldoff(lndstr, lnd_rpath), "rpath"},
     {NSC_UCHAR, 0, 0, fldoff(lndstr, lnd_rad_max), "react"},
     NSC_IVEC(fldoff(lndstr, lnd_item), ""),
     {NSC_USHORT, NSC_DEITY, 0, fldoff(lndstr, lnd_pstage), "pstage"},
index a8923d61fcb55f1d2902f0859245fd108b5281c6..2e80912df71583033c76b44d7b4bec62dc580fb8 100644 (file)
@@ -33,6 +33,7 @@
  *     Markus Armbruster, 2004
  */
 
+#include <limits.h>
 #include "misc.h"
 #include "file.h"
 #include "match.h"
@@ -132,6 +133,15 @@ nstr_comp(struct nscstr *np, int len, int type, char *str)
     return i + 1;
 }
 
+static int
+strnncmp(char *s1, size_t sz1, char *s2, size_t sz2)
+{
+    if (sz1 == sz2) return strncmp(s1, s2, sz2);
+    if (sz1 < sz2) return -strnncmp(s2, sz2, s1, sz1);
+    int res = strncmp(s1, s2, sz2);
+    return res ? res : s1[sz2];
+}
+
 #define EVAL(op, lft, rgt)                     \
     ((op) == '<' ? (lft) < (rgt)               \
      : (op) == '=' ? (lft) == (rgt)            \
@@ -171,7 +181,8 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr)
                return 0;
            break;
        case NSC_STRING:
-           cmp = strcmp(lft.val_as.str, rgt.val_as.str);
+           cmp = strnncmp(lft.val_as.str.base, lft.val_as.str.maxsz,
+                          rgt.val_as.str.base, rgt.val_as.str.maxsz);
            if (!EVAL(op, cmp, 0))
                return 0;
            break;
@@ -237,6 +248,7 @@ nstr_comp_val(char *str, struct valstr*val, int type)
                        val->val_type = cap[j].ca_type;
                        val->val_cat = NSC_OFF;
                        val->val_as.sym.off = cap[j].ca_off;
+                       val->val_as.sym.len = cap[j].ca_len;
                        val->val_as.sym.idx = 0;
                    }
                }
@@ -409,7 +421,7 @@ void
 nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
 {
     char *memb_ptr;
-    nsc_type valtype = NSC_LONG;
+    nsc_type valtype;
     int idx;
 
     switch (val->val_cat) {
@@ -420,6 +432,7 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
        valtype = val->val_type;
        break;
     case NSC_OFF:
+       valtype = NSC_LONG;
        memb_ptr = ptr;
        memb_ptr += val->val_as.sym.off;
        idx = val->val_as.sym.idx;
@@ -458,11 +471,13 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
            break;
        case NSC_STRINGY:
            CANT_HAPPEN(idx);
-           val->val_as.str = (char *)memb_ptr;
+           val->val_as.str.maxsz = val->val_as.sym.len;
+           val->val_as.str.base = (char *)memb_ptr;
            valtype = NSC_STRING;
            break;
        case NSC_STRING:
-           val->val_as.str = ((char **)memb_ptr)[idx];
+           val->val_as.str.base = ((char **)memb_ptr)[idx];
+           val->val_as.str.maxsz = INT_MAX;
            valtype = NSC_STRING;
            break;
        case NSC_TIME:
@@ -488,13 +503,14 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
        }
     } else if (want == NSC_STRING)
        CANT_HAPPEN("unimplemented WANT"); /* FIXME */
+
     if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
        valtype = want;
        switch (want) {
        case NSC_TYPEID:
        case NSC_LONG: val->val_as.lng = 0; break;
        case NSC_DOUBLE: val->val_as.dbl = 0.0; break;
-       case NSC_STRING: val->val_as.str = ""; break;
+       case NSC_STRING: val->val_as.str.base = NULL; break;
        default:
            CANT_HAPPEN("bad WANT argument");
        }