/* * 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); }
/* * 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); }
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; }