(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.
This commit is contained in:
parent
66eaa28f92
commit
630e8e105a
4 changed files with 40 additions and 15 deletions
|
@ -97,11 +97,15 @@ struct valstr {
|
||||||
union {
|
union {
|
||||||
struct { /* cat NSC_OFF */
|
struct { /* cat NSC_OFF */
|
||||||
ptrdiff_t off;
|
ptrdiff_t off;
|
||||||
|
int len;
|
||||||
int idx;
|
int idx;
|
||||||
} sym;
|
} sym;
|
||||||
double dbl; /* cat NSC_VAL, type NSC_DOUBLE */
|
double dbl; /* cat NSC_VAL, type NSC_DOUBLE */
|
||||||
char *str; /* cat NSC_VAL, type NSC_STRING */
|
struct { /* cat NSC_VAL, type NSC_STRING */
|
||||||
long lng; /* cat NSC_VAL, type NSC_LONG */
|
char *base;
|
||||||
|
size_t maxsz;
|
||||||
|
} str;
|
||||||
|
long lng; /* cat NSC_VAL, type NSC_LONG, NSC_TYPEID */
|
||||||
} val_as;
|
} val_as;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -294,7 +294,7 @@ xdeval(struct valstr *val, nsc_type type, void *ptr, ptrdiff_t off, int idx)
|
||||||
static char *
|
static char *
|
||||||
xdprval(struct valstr *val, char *sep)
|
xdprval(struct valstr *val, char *sep)
|
||||||
{
|
{
|
||||||
unsigned char *s, *e;
|
unsigned char *s, *e, *l;
|
||||||
|
|
||||||
switch (val->val_type) {
|
switch (val->val_type) {
|
||||||
case NSC_TYPEID:
|
case NSC_TYPEID:
|
||||||
|
@ -305,14 +305,17 @@ xdprval(struct valstr *val, char *sep)
|
||||||
pr("%s%#g", sep, val->val_as.dbl);
|
pr("%s%#g", sep, val->val_as.dbl);
|
||||||
break;
|
break;
|
||||||
case NSC_STRING:
|
case NSC_STRING:
|
||||||
s = (unsigned char *)val->val_as.str;
|
s = (unsigned char *)val->val_as.str.base;
|
||||||
if (s) {
|
if (s) {
|
||||||
pr("%s\"", sep);
|
pr("%s\"", sep);
|
||||||
while (*s) {
|
l = s + val->val_as.str.maxsz;
|
||||||
for (e = s; *e != '"' && *e != '\\' && isgraph(*e); ++e) ;
|
for (;;) {
|
||||||
|
for (e=s; e<l && *e != '"' && *e != '\\' && isgraph(*e); ++e) ;
|
||||||
pr("%.*s", (int)(e-s), s);
|
pr("%.*s", (int)(e-s), s);
|
||||||
if (*e)
|
if (e < l && *e)
|
||||||
pr("\\%03o", *e++);
|
pr("\\%03o", *e++);
|
||||||
|
else
|
||||||
|
break;
|
||||||
s = e;
|
s = e;
|
||||||
}
|
}
|
||||||
prnf("\"");
|
prnf("\"");
|
||||||
|
@ -455,7 +458,7 @@ xdchr(int chridx)
|
||||||
val.val_as.sym.off = cm->ca[0].ca_off;
|
val.val_as.sym.off = cm->ca[0].ca_off;
|
||||||
val.val_as.sym.idx = 0;
|
val.val_as.sym.idx = 0;
|
||||||
nstr_exec_val(&val, player->cnum, p, NSC_STRING);
|
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;
|
break;
|
||||||
++n;
|
++n;
|
||||||
xdflds(cm->ca, p);
|
xdflds(cm->ca, p);
|
||||||
|
|
|
@ -153,7 +153,8 @@ struct castr ship_ca[] = {
|
||||||
{NSC_XCOORD, NSC_DEITY, 0, fldoff(shpstr, shp_orig_x), "xbuilt"},
|
{NSC_XCOORD, NSC_DEITY, 0, fldoff(shpstr, shp_orig_x), "xbuilt"},
|
||||||
{NSC_YCOORD, NSC_DEITY, 0, fldoff(shpstr, shp_orig_y), "ybuilt"},
|
{NSC_YCOORD, NSC_DEITY, 0, fldoff(shpstr, shp_orig_y), "ybuilt"},
|
||||||
{NSC_NATID, NSC_DEITY, 0, fldoff(shpstr, shp_orig_own), "builder"},
|
{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}
|
{NSC_NOTYPE, 0, 0, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -182,7 +183,8 @@ struct castr land_ca[] = {
|
||||||
{NSC_SHORT, 0, 0, fldoff(lndstr, lnd_retreat), "retreat"},
|
{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_fuel), "fuel"},
|
||||||
{NSC_UCHAR, 0, 0, fldoff(lndstr, lnd_nxlight), "nxlight"},
|
{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_UCHAR, 0, 0, fldoff(lndstr, lnd_rad_max), "react"},
|
||||||
NSC_IVEC(fldoff(lndstr, lnd_item), ""),
|
NSC_IVEC(fldoff(lndstr, lnd_item), ""),
|
||||||
{NSC_USHORT, NSC_DEITY, 0, fldoff(lndstr, lnd_pstage), "pstage"},
|
{NSC_USHORT, NSC_DEITY, 0, fldoff(lndstr, lnd_pstage), "pstage"},
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
* Markus Armbruster, 2004
|
* Markus Armbruster, 2004
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
#include "file.h"
|
#include "file.h"
|
||||||
#include "match.h"
|
#include "match.h"
|
||||||
|
@ -132,6 +133,15 @@ nstr_comp(struct nscstr *np, int len, int type, char *str)
|
||||||
return i + 1;
|
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) \
|
#define EVAL(op, lft, rgt) \
|
||||||
((op) == '<' ? (lft) < (rgt) \
|
((op) == '<' ? (lft) < (rgt) \
|
||||||
: (op) == '=' ? (lft) == (rgt) \
|
: (op) == '=' ? (lft) == (rgt) \
|
||||||
|
@ -171,7 +181,8 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr)
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
case NSC_STRING:
|
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))
|
if (!EVAL(op, cmp, 0))
|
||||||
return 0;
|
return 0;
|
||||||
break;
|
break;
|
||||||
|
@ -237,6 +248,7 @@ nstr_comp_val(char *str, struct valstr*val, int type)
|
||||||
val->val_type = cap[j].ca_type;
|
val->val_type = cap[j].ca_type;
|
||||||
val->val_cat = NSC_OFF;
|
val->val_cat = NSC_OFF;
|
||||||
val->val_as.sym.off = cap[j].ca_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;
|
val->val_as.sym.idx = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -409,7 +421,7 @@ void
|
||||||
nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
|
nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
|
||||||
{
|
{
|
||||||
char *memb_ptr;
|
char *memb_ptr;
|
||||||
nsc_type valtype = NSC_LONG;
|
nsc_type valtype;
|
||||||
int idx;
|
int idx;
|
||||||
|
|
||||||
switch (val->val_cat) {
|
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;
|
valtype = val->val_type;
|
||||||
break;
|
break;
|
||||||
case NSC_OFF:
|
case NSC_OFF:
|
||||||
|
valtype = NSC_LONG;
|
||||||
memb_ptr = ptr;
|
memb_ptr = ptr;
|
||||||
memb_ptr += val->val_as.sym.off;
|
memb_ptr += val->val_as.sym.off;
|
||||||
idx = val->val_as.sym.idx;
|
idx = val->val_as.sym.idx;
|
||||||
|
@ -458,11 +471,13 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
|
||||||
break;
|
break;
|
||||||
case NSC_STRINGY:
|
case NSC_STRINGY:
|
||||||
CANT_HAPPEN(idx);
|
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;
|
valtype = NSC_STRING;
|
||||||
break;
|
break;
|
||||||
case NSC_STRING:
|
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;
|
valtype = NSC_STRING;
|
||||||
break;
|
break;
|
||||||
case NSC_TIME:
|
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)
|
} else if (want == NSC_STRING)
|
||||||
CANT_HAPPEN("unimplemented WANT"); /* FIXME */
|
CANT_HAPPEN("unimplemented WANT"); /* FIXME */
|
||||||
|
|
||||||
if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
|
if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
|
||||||
valtype = want;
|
valtype = want;
|
||||||
switch (want) {
|
switch (want) {
|
||||||
case NSC_TYPEID:
|
case NSC_TYPEID:
|
||||||
case NSC_LONG: val->val_as.lng = 0; break;
|
case NSC_LONG: val->val_as.lng = 0; break;
|
||||||
case NSC_DOUBLE: val->val_as.dbl = 0.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:
|
default:
|
||||||
CANT_HAPPEN("bad WANT argument");
|
CANT_HAPPEN("bad WANT argument");
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue