コード例 #1
0
/*
 * Return operator type for operand types @lft, @rgt.
 */
static int
nstr_optype(enum nsc_type lft, enum nsc_type rgt)
{
    lft = nstr_promote(lft);
    rgt = nstr_promote(rgt);
    if (lft == rgt)
	return lft;
    if (lft == NSC_DOUBLE && rgt == NSC_LONG)
	return NSC_DOUBLE;
    if (rgt == NSC_DOUBLE && lft == NSC_LONG)
	return NSC_DOUBLE;
    return NSC_NOTYPE;
}
コード例 #2
0
/*
 * Change @val to resolve identifier to value @selval for selector @ca.
 * Return @val.
 * @val must be an identifier, and @selval must have been obtained from
 * nstr_match_val(@val, CA0, @idx), where @ca = &CA0[@IDX].
 */
static struct valstr *
nstr_resolve_val(struct valstr *val, int selval, struct castr *ca)
{
    enum nsc_type type = nstr_promote(ca->ca_type);

    if (CANT_HAPPEN(val->val_cat != NSC_ID)) {
	val->val_cat = NSC_NOCAT;
	return val;
    }

    if (type == NSC_STRING) {
	val->val_type = NSC_STRING;
	val->val_cat = NSC_VAL;
	/* map identifier ~ to empty string, like some commands do */
	if (val->val_as.str.maxsz == 1 && val->val_as.str.base[0] == '~')
	    val->val_as.str.maxsz = 0;
	return val;
    }

    if (CANT_HAPPEN(type != NSC_LONG || ca->ca_table == EF_BAD)) {
	val->val_type = NSC_NOTYPE;
	val->val_cat = NSC_NOCAT;
	return val;
    }

    val->val_type = type;
    val->val_cat = NSC_VAL;
    val->val_as.lng = selval;
    return val;
}
コード例 #3
0
/*
 * Match @val in a selector's values, return its (non-negative) value.
 * Match values of selector descriptor @ca[@idx], provided @idx is not
 * negative.  @ca may be null when @idx is negative.
 * Return M_NOTFOUND if there are no matches, M_NOTUNIQUE if there are
 * several.
 */
static int
nstr_match_val(struct valstr *val, struct castr *ca, int idx)
{
    char id[32];
    enum nsc_type type;

    if (val->val_cat != NSC_ID || idx < 0)
	return M_NOTFOUND;

    type = nstr_promote(ca[idx].ca_type);
    if (type == NSC_STRING)
	return 0;

    if (ca[idx].ca_table == EF_BAD || CANT_HAPPEN(type != NSC_LONG))
	return M_NOTFOUND;

    if (val->val_as.str.maxsz >= sizeof(id))
	return M_NOTFOUND;
    memcpy(id, val->val_as.str.base, val->val_as.str.maxsz);
    id[val->val_as.str.maxsz] = 0;
    return ef_elt_byname(ca[idx].ca_table, id);
}
コード例 #4
0
ファイル: surv.c プロジェクト: fstltna/empserver
/*
 * survey type <sarg> ?cond
 *
 */
int
surv(void)
{
    int nsect;
    struct nstr_sect nstr;
    int y;
    struct valstr val;
    struct natstr *np;
    struct sctstr sect;
    struct range range;
    char *ptr;
    struct nscstr cond[NS_NCOND];
    int ncond;
    int i;
    char buf[1024];
    /* Note this is not re-entrant anyway, so we keep the buffers
       around */
    static char *mapbuf = NULL;
    static char **map = NULL;

    nsect = 0;
    ptr = getstarg(player->argp[1], "commodity or variable? ", buf);
    if (!ptr || !*ptr)
	return RET_SYN;
    ptr = nstr_comp_val(ptr, &val, EF_SECTOR);
    if (!ptr)
	return RET_SYN;
    if (val.val_cat != NSC_OFF || nstr_promote(val.val_type) != NSC_LONG) {
	pr("Can't survey this\n");
	return RET_SYN;
    }
    for (; isspace(*ptr); ++ptr) ;
    if (*ptr)
	return RET_SYN;
    if (!snxtsct(&nstr, player->argp[2]))
	return RET_SYN;
    if (!mapbuf)
	mapbuf = malloc(WORLD_Y * MAPWIDTH(1));
    if (!map) {
	map = malloc(WORLD_Y * sizeof(char *));
	if (map && mapbuf) {
	    for (i = 0; i < WORLD_Y; i++)
		map[i] = &mapbuf[MAPWIDTH(1) * i];
	} else if (map) {
	    free(map);
	    map = NULL;
	}
    }
    if (!mapbuf || !map) {
	pr("Memory error, tell the deity.\n");
	logerror("malloc failed in sect\n");
	return RET_FAIL;
    }
    ncond = nstr.ncond;
    memcpy(cond, nstr.cond, sizeof(struct nscstr) * ncond);
    nstr.ncond = 0;
    np = getnatp(player->cnum);
    xyrelrange(np, &nstr.range, &range);
    border(&range, "     ", "");
    blankfill(mapbuf, &nstr.range, 1);
    while (nxtsct(&nstr, &sect)) {
	if (!player->owner)
	    continue;
	ptr = &map[nstr.dy][nstr.dx];
	if (nstr_exec(cond, ncond, &sect)) {
	    ++nsect;
	    *ptr = 0x80 | code_char(val, &sect);
	} else {
	    *ptr = dchr[sect.sct_type].d_mnem;
	}
    }
    for (y = nstr.range.ly, i = 0; i < nstr.range.height; y++, i++) {
	int yval;

	yval = yrel(np, y);
	pr("%4d %s %4d\n", yval, map[i], yval);
	if (y >= WORLD_Y)
	    y -= WORLD_Y;
    }
    border(&range, "     ", "");
    if (nsect > 0)
	pr("\n%d sector%s.\n", nsect, splur(nsect));
    return RET_OK;
}