From 612f2dadb8a2c52dcaba1ad74aa2fcc74a79f6a3 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Fri, 20 Aug 2004 12:21:04 +0000 Subject: [PATCH] (valstr): Replace member val_as.off by val_as.sym, which contains offset and index. This is for the new dumps; conditions can't use it, yet. (nstr_comp_val): Zero index. (nstr_exec_val): Implement index. (nstr_exec_val): Simplify coercion to WANT. --- include/nsc.h | 14 +++++---- src/lib/subs/nstr.c | 73 +++++++++++++++++++++++---------------------- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/include/nsc.h b/include/nsc.h index 59aa5117..08ca9200 100644 --- a/include/nsc.h +++ b/include/nsc.h @@ -78,11 +78,12 @@ typedef unsigned char nsc_flags; /* * Value, possibly symbolic. * If type is NSC_NOTYPE, it's an error value. - * If category is NSC_OFF, the value is at offset val_as.off in the - * context object. + * If category is NSC_OFF, the value is in a context object at offset + * val_as.sym.off + val_as.sym.idx * S, where S is the size of the + * value. * If category is NSC_VAL, the value is in val_as, and the type is a * promoted type. - * Some values can also be interpreted as an object type. The values + * Some values can also be interpreted as an object type. The value's * consumer chooses how to interpret it, depending on context. */ struct valstr { @@ -90,8 +91,11 @@ struct valstr { packed_nsc_cat val_cat; /* category of value */ signed char val_as_type; /* value interpreted as object type */ union { - ptrdiff_t off; /* cat NSC_OFF */ - double dbl; /* cat NSC_VAL, types NSC_DOUBLE */ + struct { /* cat NSC_OFF */ + ptrdiff_t off; + int idx; + } sym; + double dbl; /* cat NSC_VAL, type NSC_DOUBLE */ char *str; /* cat NSC_VAL, type NSC_STRING */ long lng; /* cat NSC_VAL, type NSC_LONG */ } val_as; diff --git a/src/lib/subs/nstr.c b/src/lib/subs/nstr.c index 5bfaeb33..8ea8c822 100644 --- a/src/lib/subs/nstr.c +++ b/src/lib/subs/nstr.c @@ -187,6 +187,8 @@ nstr_exec(struct nscstr *np, int ncond, void *ptr) * Return a pointer to the first character after the value on success, * NULL on error. * TYPE is the context type, a file type. + * If STR names an array, VAL simply refers to the element with index + * zero. */ char * nstr_comp_val(char *str, struct valstr*val, int type) @@ -232,7 +234,8 @@ nstr_comp_val(char *str, struct valstr*val, int type) else { val->val_type = cap[j].ca_type; val->val_cat = NSC_OFF; - val->val_as.off = cap[j].ca_off; + val->val_as.sym.off = cap[j].ca_off; + val->val_as.sym.idx = 0; } } } else @@ -391,8 +394,8 @@ nstr_coerce_val(struct valstr *val, nsc_type to, char *str) * Use coordinate system of country CNUM. * PTR points to a context object of the type that was used to compile * the value. - * If WANT is not zero, coerce the value to promoted value type WANT. - * VAL must be coercible. That's the case if a previous + * 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 @@ -400,6 +403,7 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want) { char *memb_ptr; nsc_type valtype = NSC_LONG; + int idx; switch (val->val_cat) { default: @@ -410,38 +414,39 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want) break; case NSC_OFF: memb_ptr = ptr; - memb_ptr += val->val_as.off; + memb_ptr += val->val_as.sym.off; + idx = val->val_as.sym.idx; switch (val->val_type) { case NSC_CHAR: - val->val_as.lng = *(signed char *)memb_ptr; + val->val_as.lng = ((signed char *)memb_ptr)[idx]; break; case NSC_UCHAR: - val->val_as.lng = *(unsigned char *)memb_ptr; + val->val_as.lng = ((unsigned char *)memb_ptr)[idx]; break; case NSC_SHORT: - val->val_as.lng = *(short *)memb_ptr; + val->val_as.lng = ((short *)memb_ptr)[idx]; break; case NSC_USHORT: - val->val_as.lng = *(unsigned short *)memb_ptr; + val->val_as.lng = ((unsigned short *)memb_ptr)[idx]; break; case NSC_INT: - val->val_as.lng = *(int *)memb_ptr; + val->val_as.lng = ((int *)memb_ptr)[idx]; break; case NSC_LONG: - val->val_as.lng = *(long *)memb_ptr; + val->val_as.lng = ((long *)memb_ptr)[idx]; break; case NSC_XCOORD: - val->val_as.lng = xrel(getnatp(cnum), *(short *)memb_ptr); + val->val_as.lng = xrel(getnatp(cnum), ((short *)memb_ptr)[idx]); break; case NSC_YCOORD: - val->val_as.lng = yrel(getnatp(cnum), *(short *)memb_ptr); + val->val_as.lng = yrel(getnatp(cnum), ((short *)memb_ptr)[idx]); break; case NSC_FLOAT: - val->val_as.dbl = *(float *)memb_ptr; + val->val_as.dbl = ((float *)memb_ptr)[idx]; valtype = NSC_DOUBLE; break; case NSC_DOUBLE: - val->val_as.dbl = *(double *)memb_ptr; + val->val_as.dbl = ((double *)memb_ptr)[idx]; valtype = NSC_DOUBLE; break; case NSC_STRING: @@ -449,10 +454,10 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want) valtype = NSC_STRING; break; case NSC_TIME: - val->val_as.lng = *(time_t *)memb_ptr; + val->val_as.lng = ((time_t *)memb_ptr)[idx]; break; case NSC_TYPEID: - val->val_as.lng = *(signed char *)memb_ptr; + val->val_as.lng = ((signed char *)memb_ptr)[idx]; valtype = NSC_TYPEID; break; default: @@ -461,26 +466,24 @@ nstr_exec_val(struct valstr *val, natid cnum, void *ptr, nsc_type want) } } - if (want) { - if (valtype == want) - ; - else if (want == NSC_DOUBLE) { - if (valtype == NSC_LONG) { - valtype = want; - val->val_as.dbl = val->val_as.lng; - } - } else if (want == NSC_STRING) - CANT_HAPPEN("unimplemented WANT"); /* FIXME */ - if (CANT_HAPPEN(valtype != want)) { + if (valtype == want) + ; + else if (want == NSC_DOUBLE) { + if (valtype == NSC_LONG) { valtype = want; - switch (want) { - case NSC_TYPEID: - 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 = ""; break; - default: - CANT_HAPPEN("bad WANT argument"); - } + val->val_as.dbl = val->val_as.lng; + } + } else if (want == NSC_STRING) + CANT_HAPPEN("unimplemented WANT"); /* FIXME */ + if (CANT_HAPPEN(valtype != want && want != NSC_NOTYPE)) { + valtype = want; + switch (want) { + case NSC_TYPEID: + 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 = ""; break; + default: + CANT_HAPPEN("bad WANT argument"); } }