00001
00002
00003
00004
00005
00006
00007
00008 #include <stdlib.h>
00009 #include <stdio.h>
00010 #include <errno.h>
00011 #include <math.h>
00012 #include <complex.h>
00013
00014 #include "int_assert.h"
00015
00016 EXPORT_CREATE(int_assert);
00017 EXPORT_INIT(int_assert);
00018 EXPORT_COMMIT(int_assert);
00019 EXPORT_NOTIFY(int_assert);
00020
00021 CLASS *int_assert::oclass = NULL;
00022 int_assert *int_assert::defaults = NULL;
00023
00024 int_assert::int_assert(MODULE *module)
00025 {
00026 if (oclass==NULL)
00027 {
00028
00029 oclass = gl_register_class(module,"int_assert",sizeof(int_assert),PC_AUTOLOCK|PC_OBSERVER);
00030 if (oclass==NULL)
00031 throw "unable to register class int_assert";
00032 else
00033 oclass->trl = TRL_PROVEN;
00034
00035 if (gl_publish_variable(oclass,
00036
00037 PT_enumeration,"status",get_status_offset(),
00038 PT_KEYWORD,"ASSERT_TRUE",(enumeration)ASSERT_TRUE,
00039 PT_KEYWORD,"ASSERT_FALSE",(enumeration)ASSERT_FALSE,
00040 PT_KEYWORD,"ASSERT_NONE",(enumeration)ASSERT_NONE,
00041 PT_enumeration, "once", get_once_offset(),
00042 PT_KEYWORD,"ONCE_FALSE",(enumeration)ONCE_FALSE,
00043 PT_KEYWORD,"ONCE_TRUE",(enumeration)ONCE_TRUE,
00044 PT_KEYWORD,"ONCE_DONE",(enumeration)ONCE_DONE,
00045 PT_enumeration, "within_mode", get_within_mode_offset(),
00046 PT_KEYWORD,"WITHIN_VALUE",(enumeration)IN_ABS,
00047 PT_KEYWORD,"WITHIN_RATIO",(enumeration)IN_RATIO,
00048 PT_int32, "value", get_value_offset(),
00049 PT_int32, "within", get_within_offset(),
00050 PT_char1024, "target", get_target_offset(),
00051 NULL)<1){
00052 char msg[256];
00053 sprintf(msg, "unable to publish properties in %s",__FILE__);
00054 throw msg;
00055 }
00056
00057 defaults = this;
00058 status = ASSERT_TRUE;
00059 within = 0;
00060 within_mode = IN_ABS;
00061 value = 0;
00062 once = ONCE_FALSE;
00063 once_value = 0;
00064 }
00065 }
00066
00067
00068 int int_assert::create(void)
00069 {
00070 memcpy(this,defaults,sizeof(*this));
00071
00072 return 1;
00073 }
00074
00075 int int_assert::init(OBJECT *parent)
00076 {
00077 char *msg = "A negative value has been specified for within.";
00078 if (within < 0)
00079 throw msg;
00080
00081
00082
00083
00084 return 1;
00085 }
00086
00087 TIMESTAMP int_assert::commit(TIMESTAMP t1, TIMESTAMP t2)
00088 {
00089
00090 if ( once==ONCE_TRUE )
00091 {
00092 once_value = value;
00093 once = ONCE_DONE;
00094 }
00095 else if ( once == ONCE_DONE )
00096 {
00097 if ( once_value==value )
00098 {
00099 gl_verbose("Assert skipped with ONCE logic");
00100 return TS_NEVER;
00101 }
00102 else
00103 {
00104 once_value = value;
00105 }
00106 }
00107
00108
00109 gld_property target_prop(get_parent(),get_target());
00110 if ( !target_prop.is_valid() || !(target_prop.get_type()==PT_int16 || target_prop.get_type()==PT_int32 || target_prop.get_type()==PT_int64))
00111 {
00112 gl_error("Specified target %s for %s is not valid.",get_target(),get_parent()->get_name());
00113
00114
00115
00116
00117
00118
00119 return 0;
00120 }
00121
00122
00123 int range = 0;
00124 if ( within_mode == IN_RATIO )
00125 {
00126 range = value * within;
00127 if ( range < 1 )
00128 {
00129 range = 1;
00130 }
00131 }
00132 else if ( within_mode== IN_ABS )
00133 {
00134 range = within;
00135 }
00136
00137
00138 int64 x; target_prop.getp(x);
00139 if ( status == ASSERT_TRUE )
00140 {
00141 int64 theDiff = x-value;
00142 if(theDiff > 0xFFFFFFFF || theDiff < -0xFFFFFFFF){
00143 gl_warning("int_assert may be incorrect, difference range outside 32-bit abs() range");
00144 }
00145 int64 m = fabs((double) theDiff);
00146 if ( m>range )
00147 {
00148 gl_error("Assert failed on %s: %s %i not within %i of given value %i",
00149 get_parent()->get_name(), get_target(), x, range, value);
00150 return 0;
00151 }
00152 gl_verbose("Assert passed on %s", get_parent()->get_name());
00153 return TS_NEVER;
00154 }
00155 else if ( status == ASSERT_FALSE )
00156 {
00157 int64 theDiff = x-value;
00158 if(theDiff > 0xFFFFFFFF || theDiff < -0xFFFFFFFF){
00159 gl_warning("int_assert may be incorrect, difference range outside 32-bit abs() range");
00160 }
00161 int64 m = fabs((double) theDiff);
00162 if ( m<range )
00163 {
00164 gl_error("Assert failed on %s: %s %i is within %i of given value %i",
00165 get_parent()->get_name(), get_target(), x, range, value);
00166 return 0;
00167 }
00168 gl_verbose("Assert passed on %s", get_parent()->get_name());
00169 return TS_NEVER;
00170 }
00171 else
00172 {
00173 gl_verbose("Assert test is not being run on %s", get_parent()->get_name());
00174 return TS_NEVER;
00175 }
00176
00177 }
00178
00179 int int_assert::postnotify(PROPERTY *prop, char *value)
00180 {
00181 if ( once==ONCE_DONE && strcmp(prop->name, "value")==0 )
00182 {
00183 once = ONCE_TRUE;
00184 }
00185 return 1;
00186 }