#include <config.h>
#include <limits.h>
+#include <string.h>
#include "file.h"
#include "nat.h"
#include "nsc.h"
/*
* Evaluate VAL.
* If VAL is symbolic, evaluate it into a promoted value type.
- * Use coordinate system of country CNUM.
+ * Use country CNUM's coordinate system and access control.
* PTR points to a context object of the type that was used to compile
* the value.
* Unless WANT is NSC_NOTYPE, coerce the value to promoted value type
* WANT. VAL must be coercible. That's the case if a previous
* nstr_coerce_val(VAL, WANT, STR) succeeded.
*/
-void
+struct valstr *
nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want)
{
char *memb_ptr;
int idx;
struct natstr *natp;
+ if (CANT_HAPPEN(want != NSC_NOTYPE && !NSC_IS_PROMOTED(want)))
+ want = nstr_promote(want);
+
switch (val->val_cat) {
- default:
- CANT_REACH();
- /* fall through */
case NSC_VAL:
valtype = val->val_type;
break;
case NSC_OFF:
+ if (val->val_as.sym.get) {
+ do {
+ ptr = val->val_as.sym.get(val, cnum, ptr);
+ } while (ptr && val->val_as.sym.get);
+ if (!ptr) {
+ valtype = val->val_type;
+ val->val_cat = NSC_VAL;
+ break;
+ }
+ }
+
valtype = NSC_LONG;
memb_ptr = ptr;
memb_ptr += val->val_as.sym.off;
val->val_as.lng = 0;
}
val->val_cat = NSC_VAL;
+ break;
+ default:
+ CANT_REACH();
+ valtype = NSC_NOTYPE;
}
if (valtype == want)
CANT_REACH(); /* FIXME implement */
if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) {
+ /* make up an error value */
valtype = want;
- switch (want) {
- 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;
- default:
- CANT_REACH();
- }
+ memset(&val->val_as, 0, sizeof(val->val_as));
}
val->val_type = valtype;
+ return val;
}
/*