From 630e8e105ab1ef2f0c35df7fe83cac87abd99851 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sat, 11 Sep 2004 08:45:17 +0000 Subject: [PATCH] (valstr, nstr_exec, nstr_comp_val, nstr_exec_val, xdprval): Support 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 | 8 ++++++-- src/lib/commands/xdump.c | 15 +++++++++------ src/lib/global/nsc.c | 6 ++++-- src/lib/subs/nstr.c | 26 +++++++++++++++++++++----- 4 files changed, 40 insertions(+), 15 deletions(-) diff --git a/include/nsc.h b/include/nsc.h index d2f022af..545f23d7 100644 --- a/include/nsc.h +++ b/include/nsc.h @@ -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; }; diff --git a/src/lib/commands/xdump.c b/src/lib/commands/xdump.c index e9fe6103..94f31aae 100644 --- a/src/lib/commands/xdump.c +++ b/src/lib/commands/xdump.c @@ -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; eca[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); diff --git a/src/lib/global/nsc.c b/src/lib/global/nsc.c index ea23f1a6..c8f151dd 100644 --- a/src/lib/global/nsc.c +++ b/src/lib/global/nsc.c @@ -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"}, diff --git a/src/lib/subs/nstr.c b/src/lib/subs/nstr.c index a8923d61..2e80912d 100644 --- a/src/lib/subs/nstr.c +++ b/src/lib/subs/nstr.c @@ -33,6 +33,7 @@ * Markus Armbruster, 2004 */ +#include #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"); }