int
saf_quantify_unit(SAF_ParMode pmode,
SAF_Unit *unit, /* The unit whose quantity information is being set. */
SAF_Quantity *quantity,/* The quantity which this unit measures. */
double scale /* This argument can be used to defined a new unit as some scale of the base unit for
* the quantity without requiring the unit definition to include a multiplication by
* the base unit. The SCALE is multiplied into any scale which is already present. */
)
{
SAF_ENTER(saf_quantify_unit, SAF_PRECONDITION_ERROR);
SAF_REQUIRE(_saf_valid_pmode(pmode), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("PMODE must be valid"));
if (!_saf_is_participating_proc(pmode)) SAF_RETURN(-1);
SAF_REQUIRE(SS_UNIT(unit), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("UNIT must be a valid unit handle"));
SAF_REQUIRE(SS_QUANTITY(quantity), SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("QUANTITY must be a valid quantity handle"));
SAF_REQUIRE(scale>0.0, SAF_LOW_CHK_COST, SAF_PRECONDITION_ERROR,
_saf_errmsg("SCALE must be positive"));
/* If UNIT already has a quantity then the new quantity must be structurally equivalent. */
if (!SS_PERS_ISNULL(SS_UNIT_P(unit,quant))) {
assert(SS_MAX_BASEQS==7);
if (SS_QUANTITY(SS_UNIT_P(unit,quant))->flags != SS_QUANTITY(quantity)->flags ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[0] != SS_QUANTITY(quantity)->power[0] ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[1] != SS_QUANTITY(quantity)->power[1] ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[2] != SS_QUANTITY(quantity)->power[2] ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[3] != SS_QUANTITY(quantity)->power[3] ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[4] != SS_QUANTITY(quantity)->power[4] ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[5] != SS_QUANTITY(quantity)->power[5] ||
SS_QUANTITY(SS_UNIT_P(unit,quant))->power[6] != SS_QUANTITY(quantity)->power[6]) {
SAF_ERROR(SAF_CONTEXT_ERROR, _saf_errmsg("UNIT and QUANTITY are incompatible"));
}
}
/* Associate QUANTITY with UNIT */
SAF_DIRTY(unit, pmode);
SS_UNIT(unit)->quant = *quantity;
SS_UNIT(unit)->scale *= scale;
SAF_LEAVE(SAF_SUCCESS);
}