diff --git a/include/file.h b/include/file.h index 46346470..073762e0 100644 --- a/include/file.h +++ b/include/file.h @@ -177,6 +177,7 @@ extern int ef_byname(char *); extern int ef_byname_from(char *, int *); extern void ef_init(void); extern int ef_verify(void); +extern int ef_elt_byname(int, char *); extern struct empfile empfile[EF_MAX + 1]; diff --git a/include/nsc.h b/include/nsc.h index fc20d0fa..dcecec1f 100644 --- a/include/nsc.h +++ b/include/nsc.h @@ -48,7 +48,6 @@ typedef enum { NSC_LONG, /* long */ NSC_DOUBLE, /* double */ NSC_STRING, /* char *, zero-terminated string */ - NSC_TYPEID, /* signed char, index into chr table */ /* unpromoted types */ NSC_CHAR, /* signed char */ NSC_UCHAR, /* unsigned char */ @@ -116,7 +115,7 @@ struct valstr { char *base; size_t maxsz; } str; - long lng; /* cat NSC_VAL, type NSC_LONG, NSC_TYPEID */ + long lng; /* cat NSC_VAL, type NSC_LONG */ } val_as; }; diff --git a/src/lib/commands/xdump.c b/src/lib/commands/xdump.c index ef9531ae..956260e2 100644 --- a/src/lib/commands/xdump.c +++ b/src/lib/commands/xdump.c @@ -112,7 +112,6 @@ xdprval(struct valstr *val, char *sep) unsigned char *s, *e, *l; switch (val->val_type) { - case NSC_TYPEID: case NSC_LONG: pr("%s%ld", sep, val->val_as.lng); break; diff --git a/src/lib/common/ef_verify.c b/src/lib/common/ef_verify.c index 6083a79e..41f5a54a 100644 --- a/src/lib/common/ef_verify.c +++ b/src/lib/common/ef_verify.c @@ -97,7 +97,7 @@ verify_row(int type, int row) val.val_as.sym.len = ca[i].ca_len; val.val_as.sym.idx = j; nstr_exec_val(&val, 0, row_ref, NSC_NOTYPE); - if (val.val_type != NSC_LONG && val.val_type != NSC_TYPEID) + if (val.val_type != NSC_LONG) continue; ca_sym = ef_cadef(ca[i].ca_table); if (ca[i].ca_flags & NSC_BITS) { diff --git a/src/lib/common/type.c b/src/lib/common/type.c index 18b0310c..44f977d9 100644 --- a/src/lib/common/type.c +++ b/src/lib/common/type.c @@ -98,3 +98,53 @@ typematch(char *name, int type) } return M_NOTFOUND; } + +/* + * Search table TYPE for an element matching NAME, return its index. + * Return M_NOTFOUND if there are no matches, M_NOTUNIQUE if there are + * several. + */ +int +ef_elt_byname(int type, char *name) +{ + switch (type) { + case EF_NATION: + return cnumb(name); + case EF_SECTOR_CHR: + return sct_typematch(name); + case EF_SHIP_CHR: + return stmtch(name, mchr, + offsetof(struct mchrstr, m_name), + sizeof(mchr[0])); + case EF_LAND_CHR: + return stmtch(name, lchr, + offsetof(struct lchrstr, l_name), + sizeof(lchr[0])); + case EF_PLANE_CHR: + return stmtch(name, plchr, + offsetof(struct plchrstr, pl_name), + sizeof(plchr[0])); + case EF_NUKE_CHR: + return stmtch(name, nchr, + offsetof(struct nchrstr, n_name), + sizeof(nchr[0])); + case EF_ITEM: + return stmtch(name, ichr, + offsetof(struct ichrstr, i_name), + sizeof(ichr[0])); + case EF_PRODUCT: + return stmtch(name, pchr + 1, + offsetof(struct pchrstr, p_sname), + sizeof(pchr[0])); + case EF_TABLE: + return stmtch(name, empfile, + offsetof(struct empfile, name), + sizeof(empfile[0])); + default: + if (ef_cadef(type) == symbol_ca) + return stmtch(name, ef_ptr(type, 0), + offsetof(struct symbol, name), + sizeof(struct symbol)); + } + return M_NOTFOUND; +} diff --git a/src/lib/common/xundump.c b/src/lib/common/xundump.c index f0566af0..1f27f5b2 100644 --- a/src/lib/common/xundump.c +++ b/src/lib/common/xundump.c @@ -447,7 +447,6 @@ setnum(int fldno, double dbl) switch (ca->ca_type) { case NSC_CHAR: - case NSC_TYPEID: old = ((signed char *)memb_ptr)[idx]; ((signed char *)memb_ptr)[idx] = (signed char)dbl; break; diff --git a/src/lib/global/nsc.c b/src/lib/global/nsc.c index 8287650a..f01147c2 100644 --- a/src/lib/global/nsc.c +++ b/src/lib/global/nsc.c @@ -123,7 +123,7 @@ struct castr sect_ca[] = { {NSC_NATID, 0, 0, fldoff(sctstr, sct_own), "owner", EF_NATION}, {NSC_XCOORD, NSC_CONST, 0, fldoff(sctstr, sct_x), "xloc", EF_BAD}, {NSC_YCOORD, NSC_CONST, 0, fldoff(sctstr, sct_y), "yloc", EF_BAD}, - {NSC_TYPEID, 0, 0, fldoff(sctstr, sct_type), "des", EF_SECTOR_CHR}, + {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_type), "des", EF_SECTOR_CHR}, {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_effic), "effic", EF_BAD}, {NSC_SHORT, 0, 0, fldoff(sctstr, sct_mobil), "mobil", EF_BAD}, {NSC_UCHAR, NSC_DEITY, 0, fldoff(sctstr, sct_loyal), "loyal", EF_BAD}, @@ -137,7 +137,7 @@ struct castr sect_ca[] = { {NSC_SHORT, 0, 0, fldoff(sctstr, sct_avail), "avail", EF_BAD}, {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_work), "work", EF_BAD}, {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_coastal), "coastal", EF_BAD}, - {NSC_TYPEID, 0, 0, fldoff(sctstr, sct_newtype), "newdes", EF_SECTOR_CHR}, + {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_newtype), "newdes", EF_SECTOR_CHR}, {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_min), "min", EF_BAD}, {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_gmin), "gold", EF_BAD}, {NSC_UCHAR, 0, 0, fldoff(sctstr, sct_fertil), "fert", EF_BAD}, @@ -193,7 +193,7 @@ struct castr dchr_ca[] = { { NSC_NATID, 0, 0, fldoff(genitem, own), "owner", EF_NATION}, \ { NSC_XCOORD, 0, 0, fldoff(genitem, x), "xloc", EF_BAD}, \ { NSC_YCOORD, 0, 0, fldoff(genitem, y), "yloc", EF_BAD}, \ -{ NSC_TYPEID, 0, 0, fldoff(genitem, type), "type", ef_chr}, \ +{ NSC_CHAR, 0, 0, fldoff(genitem, type), "type", ef_chr}, \ { NSC_CHAR, 0, 0, fldoff(genitem, effic), "effic", EF_BAD}, \ { NSC_CHAR , 0, 0, fldoff(genitem, mobil), "mobil", EF_BAD}, \ { NSC_UCHAR , 0, 0, fldoff(genitem, off), "off", EF_BAD}, \ diff --git a/src/lib/global/symbol.c b/src/lib/global/symbol.c index 5a772c45..5c7ab5d0 100644 --- a/src/lib/global/symbol.c +++ b/src/lib/global/symbol.c @@ -86,7 +86,6 @@ struct symbol meta_type[] = { {NSC_LONG, "d"}, {NSC_DOUBLE, "g"}, {NSC_STRING, "s"}, - {NSC_TYPEID, "d"}, {NSC_CHAR, "d"}, {NSC_UCHAR, "d"}, {NSC_SHORT, "d"}, diff --git a/src/lib/subs/nstr.c b/src/lib/subs/nstr.c index f6dd88c1..5941a914 100644 --- a/src/lib/subs/nstr.c +++ b/src/lib/subs/nstr.c @@ -45,7 +45,7 @@ static char *nstr_parse_val(char *, struct valstr *); static int nstr_match_ca(struct valstr *, struct castr *); -static int nstr_match_val(struct valstr *, int, struct castr *, int); +static int nstr_match_val(struct valstr *, struct castr *, int); static int nstr_string_ok(struct castr *ca, int idx); static struct valstr *nstr_resolve_sel(struct valstr *, struct castr *); static struct valstr *nstr_mkselval(struct valstr *, int, struct castr *); @@ -106,8 +106,8 @@ nstr_comp(struct nscstr *np, int len, int type, char *str) * possible. Example: nlft, type, ca, rgt_caidx); - rgt_val = nstr_match_val(&np->rgt, type, ca, lft_caidx); + lft_val = nstr_match_val(&np->lft, ca, rgt_caidx); + rgt_val = nstr_match_val(&np->rgt, ca, lft_caidx); /* * if lft_val >= 0, then rhs names a selector and lhs names * one of its values. Likewise for rgt_val. @@ -142,13 +142,7 @@ nstr_comp(struct nscstr *np, int len, int type, char *str) lft_type = nstr_promote(np->lft.val_type); rgt_type = nstr_promote(np->rgt.val_type); np->optype = NSC_NOTYPE; - if (lft_type == NSC_TYPEID) { - if (!nstr_coerce_val(&np->rgt, NSC_TYPEID, str)) - np->optype = NSC_TYPEID; - } else if (rgt_type == NSC_TYPEID) { - if (!nstr_coerce_val(&np->lft, NSC_TYPEID, str)) - np->optype = NSC_TYPEID; - } else if (lft_type == NSC_STRING) { + if (lft_type == NSC_STRING) { if (!nstr_coerce_val(&np->rgt, NSC_STRING, str)) np->optype = NSC_STRING; } else if (rgt_type == NSC_STRING) { @@ -227,7 +221,6 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr) rgt = np[i].rgt; nstr_exec_val(&rgt, player->cnum, ptr, optype); switch (optype) { - case NSC_TYPEID: case NSC_LONG: if (!EVAL(op, lft.val_as.lng, rgt.val_as.lng)) return 0; @@ -254,7 +247,8 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr) /* * Parse a value in STR into VAL. * Return a pointer to the first character after the value. - * Value is either evaluated (but not NSC_TYPEID) or an identifier. + * Value is either evaluated into NSC_STRING, NSC_DOUBLE or NSC_LONG, + * or an identifier. */ static char * nstr_parse_val(char *str, struct valstr *val) @@ -272,6 +266,7 @@ nstr_parse_val(char *str, struct valstr *val) val->val_as.str.base = str + 1; val->val_as.str.maxsz = tail - (str + 1); if (*tail) ++tail; + /* FIXME else unclosed string */ return tail; } @@ -337,31 +332,28 @@ nstr_match_ca(struct valstr *val, struct castr *ca) /* * Match VAL in a selector's values, return its (non-negative) value. - * TYPE is the context type, a file type. - * CA is ef_cadef(TYPE). If it is null, then IDX must be negative. * Match values of selector descriptor CA[IDX], provided IDX is not - * negative. + * negative. CA may be null when IDX is negative. * Return M_NOTFOUND if there are no matches, M_NOTUNIQUE if there are * several. - * TODO: This is just a stub and works only for NSC_TYPEID. - * Generalize: give struct castr enough info to find values, remove - * parameter `type'. */ static int -nstr_match_val(struct valstr *val, int type, struct castr *ca, int idx) +nstr_match_val(struct valstr *val, struct castr *ca, int idx) { char id[32]; if (val->val_cat != NSC_ID || val->val_as.str.maxsz >= sizeof(id)) return M_NOTFOUND; - if (idx < 0 || ca[idx].ca_type != NSC_TYPEID) + if (idx < 0 || ca[idx].ca_table == EF_BAD) + return M_NOTFOUND; + if (CANT_HAPPEN(nstr_promote(ca[idx].ca_type) != NSC_LONG)) return M_NOTFOUND; memcpy(id, val->val_as.str.base, val->val_as.str.maxsz); id[val->val_as.str.maxsz] = 0; - return typematch(id, type); + return ef_elt_byname(ca[idx].ca_table, id); } /* @@ -452,7 +444,8 @@ nstr_resolve_sel(struct valstr *val, struct castr *ca) static struct valstr * nstr_mkselval(struct valstr *val, int selval, struct castr *ca) { - if (CANT_HAPPEN(ca->ca_type != NSC_TYPEID)) { + if (CANT_HAPPEN(nstr_promote(ca->ca_type) != NSC_LONG + || ca->ca_table == EF_BAD)) { val->val_type = NSC_NOTYPE; val->val_cat = NSC_NOCAT; return val; @@ -487,18 +480,15 @@ nstr_comp_val(char *str, struct valstr *val, int type) * Promote VALTYPE. * If VALTYPE is an integer type, return NSC_LONG. * If VALTYPE is a floating-point type, return NSC_DOUBLE. - * If VALTYPE is NSC_STRINGY, return NSC_STRING. - * If VALTYPE is NSC_NOTYPE, NSC_STRING or NSC_TYPEID, return VALTYPE. + * If VALTYPE is a string type, return NSC_STRING. */ static int nstr_promote(int valtype) { switch (valtype) { - case NSC_NOTYPE: case NSC_LONG: case NSC_DOUBLE: case NSC_STRING: - case NSC_TYPEID: break; case NSC_CHAR: case NSC_UCHAR: @@ -550,8 +540,6 @@ nstr_coerce_val(struct valstr *val, nsc_type to, char *str) if (from != to) { switch (to) { - case NSC_TYPEID: - return cond_type_mismatch(str); case NSC_STRING: return cond_type_mismatch(str); /* FIXME implement */ case NSC_DOUBLE: @@ -667,10 +655,6 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want) case NSC_TIME: val->val_as.lng = ((time_t *)memb_ptr)[idx]; break; - case NSC_TYPEID: - val->val_as.lng = ((signed char *)memb_ptr)[idx]; - valtype = NSC_TYPEID; - break; default: CANT_REACH(); val->val_as.lng = 0; @@ -691,7 +675,6 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want) 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.base = NULL; break;