extern int ef_nelem(int);
extern int ef_flags(int);
extern int ef_byname(char *);
+extern int ef_byname_from(char *, int *);
extern struct empfile empfile[];
int
cede(void)
{
+ static int sct_or_shp[] = { EF_SECTOR, EF_SHIP, EF_BAD };
natid to;
int n;
int is_sector = 0, is_ship = 0;
return RET_FAIL;
if (strlen(p) > 4)
p[2] = 0;
- type = ef_byname(p);
-
- if (type == EF_SECTOR)
- is_ship = 0;
- else if (type == EF_SHIP)
- is_sector = 0;
- else {
+ type = ef_byname_from(p, sct_or_shp);
+ if (type < 0) {
pr("Please type 'se' or 'sh'!\n");
return RET_FAIL;
}
static int
cons_choose(struct ltcomstr *ltcp)
{
+ static int lon_or_trt[] = { EF_LOAN, EF_TREATY, EF_BAD };
s_char *p;
struct lonstr *lp;
struct trtstr *tp;
memset(ltcp, 0, sizeof(*ltcp));
if (getstarg(player->argp[1], "loan or treaty? ", buf) == 0)
return RET_SYN;
- ltcp->type = ef_byname(buf);
+ ltcp->type = ef_byname_from(buf, lon_or_trt);
switch (ltcp->type) {
case EF_TREATY:
if (!opt_TREATIES) {
int
fuel(void)
{
+ static int shp_or_lnd[] = { EF_SHIP, EF_LAND, EF_BAD };
struct nstr_item ni;
union item_u item, item2;
int type;
if ((p =
getstarg(player->argp[1], "Ship or land unit (s,l)? ", buf)) == 0)
return RET_SYN;
- type = ef_byname(p);
- if (type == EF_SECTOR)
- type = EF_SHIP;
- if (type != EF_SHIP && type != EF_LAND) {
+ type = ef_byname_from(p, shp_or_lnd);
+ if (type < 0) {
pr("Ships or land units only! (s, l)\n");
return RET_SYN;
}
int
multifire(void)
{
+ static int ef_with_guns[] = { EF_SECTOR, EF_SHIP, EF_LAND, EF_BAD };
s_char vbuf[20];
s_char *ptr;
double range2, range;
buf)))
return RET_SYN;
player->argp[1] = 0;
- type = ef_byname(p);
+ type = ef_byname_from(p, ef_with_guns);
if (type == EF_SECTOR) {
if (opt_NO_FORT_FIRE) {
pr("Fort firing is disabled.\n");
int
mission(void)
{
+ static int ef_with_missions[] = { EF_SHIP, EF_LAND, EF_PLANE, EF_BAD };
s_char *p;
int type;
int mission;
getstarg(player->argp[1], "Ship, plane or land unit (p,sh,la)? ",
buf)) == 0)
return RET_SYN;
- type = ef_byname(p);
- if (type == EF_SECTOR)
- type = EF_SHIP;
- if (type != EF_SHIP && type != EF_LAND && type != EF_PLANE) {
+ type = ef_byname_from(p, ef_with_missions);
+ if (type < 0) {
pr("Ships, land units or planes only! (s, l, p)\n");
return RET_SYN;
}
int
set(void)
{
+ static int ef_saleable[] = { EF_SHIP, EF_PLANE, EF_LAND, EF_NUKE, EF_BAD };
char *p;
int type;
int price;
check_market();
check_trade();
- if ((p = getstarg(player->argp[1], "Item type? ", buf)) == 0)
+ if ((p = getstarg(player->argp[1], "Ship, plane, land unit or nuke? ", buf)) == 0)
return RET_SYN;
- if ((type = ef_byname(p)) < 0) {
- pr("%s: not an item type\n", p);
+ if ((type = ef_byname_from(p, ef_saleable)) < 0) {
+ pr("You can sell only ships, planes, land units or nukes\n", p);
return RET_SYN;
}
- if (type == EF_SECTOR)
- type = EF_SHIP;
- if (type == EF_NEWS)
- type = EF_NUKE;
- if (type == EF_LOAN)
- type = EF_LAND;
if (!snxtitem(&ni, type, player->argp[2]))
return RET_SYN;
while (nxtitem(&ni, &item)) {
#if !defined(_WIN32)
#include <unistd.h>
#endif
-#include "misc.h"
-#include "nsc.h"
-#include "file.h"
#include "common.h"
+#include "file.h"
#include "gen.h"
-
+#include "match.h"
+#include "misc.h"
+#include "nsc.h"
static int fillcache(struct empfile *, int);
static int do_write(struct empfile *, void *, int, int);
int
ef_byname(char *name)
{
+ /* FIXME should use stmtch() */
struct empfile *ef;
int i;
int len;
return -1;
}
+/*
+ * Search CHOICES[] for a table ID matching NAME.
+ * CHOICES[] contains indexes in empfile[] and is terminated with a
+ * negative value.
+ * Return the matching index if there is one, else -1.
+ */
+int
+ef_byname_from(char *name, int choices[])
+{
+ int res;
+ int *p;
+
+ res = M_NOTFOUND;
+ for (p = choices; *p >= 0; p++) {
+ if (ef_check(*p) < 0)
+ continue;
+ switch (mineq(name, empfile[*p].name)) {
+ case ME_MISMATCH:
+ break;
+ case ME_PARTIAL:
+ if (res >= 0)
+ return M_NOTUNIQUE;
+ res = *p;
+ break;
+ case ME_EXACT:
+ return *p;
+ }
+ }
+ return res;
+}
+
char *
ef_nameof(int type)
{