예제 #1
0
파일: xdump.c 프로젝트: gefla/empserver
/*
 * Evaluate a attribute of an object into @val, return @val.
 * @ca describes the attribute.
 * @xd is the xdump descriptor.
 * @ptr points to the context object.
 * @idx is the index within the attribute.
 */
static struct valstr *
xdeval(struct valstr *val, struct xdstr *xd,
       struct castr *ca, void *ptr, int idx)
{
    nstr_mksymval(val, ca, idx);
    return nstr_eval(val, xd->cnum, ptr, NSC_NOTYPE);
}
예제 #2
0
/*
 * Change @val to resolve identifier to selector.
 * Return @val on success, NULL on error.
 * No change if @val is not an identifier.
 * Else change @val into symbolic value for selector @ca[@idx] if @idx >=
 * 0, and error if not.
 */
static struct valstr *
nstr_resolve_id(struct valstr *val, struct castr *ca, int idx)
{
    if (val->val_cat != NSC_ID)
	return val;

    if (idx == M_NOTUNIQUE) {
	pr("%.*s -- ambiguous name\n",
	   (int)val->val_as.str.maxsz, val->val_as.str.base);
	val->val_cat = NSC_NOCAT;
	return NULL;
    }

    if (idx == M_NOTFOUND) {
	pr("%.*s -- unknown name\n",
	   (int)val->val_as.str.maxsz, val->val_as.str.base);
	val->val_cat = NSC_NOCAT;
	return NULL;
    }

    if (CA_IS_ARRAY(&ca[idx])) {
	pr("%.*s -- not usable here\n",
	   (int)val->val_as.str.maxsz, val->val_as.str.base);
	val->val_cat = NSC_NOCAT;
	return NULL;
    }

    if ((ca[idx].ca_flags & NSC_DEITY) && !player->god) {
	pr("%.*s -- not accessible to mortals\n",
	   (int)val->val_as.str.maxsz, val->val_as.str.base);
	val->val_cat = NSC_NOCAT;
	return NULL;
    }

    return nstr_mksymval(val, &ca[idx], 0);
}
예제 #3
0
static int
verify_row(int type, int row)
{
    struct castr *ca = ef_cadef(type);
    struct empobj *row_ref;
    int i, j, n;
    struct valstr val;
    int ret_val = 0;
    int flags = ef_flags(type);

    if (flags & EFF_MEM)
	row_ref = ef_ptr(type, row);
    else {
	row_ref = malloc(empfile[type].size);
	ef_read(type, row, row_ref);
    }

    if ((flags & EFF_TYPED) && !EF_IS_VIEW(type)) {
	if (row_ref->ef_type != type || row_ref->uid != row) {
	    verify_fail(type, row, NULL, 0, "header corrupt");
	    ret_val = -1;
	}
    }

    if (!empobj_in_use(type, row_ref))
	goto out;

    for (i = 0; ca[i].ca_name; ++i) {
	if (ca[i].ca_get)
	    continue;		/* virtual */
	n = CA_ARRAY_LEN(&ca[i]);
	j = 0;
	do {
	    if (ca[i].ca_table == EF_BAD)
		continue;
	    nstr_mksymval(&val, &ca[i], j);
	    nstr_eval(&val, 0, row_ref, NSC_NOTYPE);
	    if (CANT_HAPPEN(val.val_type != NSC_LONG)) {
		ret_val = -1;
		continue;
	    }
	    if (ca[i].ca_table == type && i == 0) {
		/* uid */
		if (val.val_as.lng != row) {
		    verify_fail(type, row, &ca[i], j,
				"value is %ld instead of %d",
				val.val_as.lng, row);
		    ret_val = -1;
		}
	    } else {
		if (verify_tabref(type, row, &ca[i], j, val.val_as.lng) < 0)
		    ret_val = -1;
	    }
	} while (++j < n);
    }

out:
    if (!(flags & EFF_MEM))
	free(row_ref);
    return ret_val;
}