From 1f8f92fa6804cab305575e11922e60ff346e80be Mon Sep 17 00:00:00 2001 From: gscalamera <graziano.scalamera@elettra.eu> Date: Fri, 6 Dec 2024 09:16:57 +0100 Subject: [PATCH] Support 2 indexes for 2-dimensional arrays (Image) --- docs/Formula.md | 13 ++- src/AlarmHandler.cpp | 184 ++++++++++++++++++++++++++++++++---------- src/AlarmHandler.h | 2 +- src/alarm_table.h | 47 +++++++---- src/event_table.cpp | 6 +- src/event_table.h | 7 +- src/formula_grammar.h | 4 +- 7 files changed, 198 insertions(+), 65 deletions(-) diff --git a/docs/Formula.md b/docs/Formula.md index 69515cf..d731f51 100644 --- a/docs/Formula.md +++ b/docs/Formula.md @@ -99,9 +99,18 @@ The read part of every attribute is internally extracted in a vector of double w # Operation on arrays -## Index to access single element +## Indexes to access elements -A single element of an array attribute (Spectrum, Image) can be extracted with a single index between square brackets (e.g. ```name/of/dev/attr[ind]```). Since Image attributes are extracted to vectors as well, the single index can access every element as long as the size of rows is known. Accessing an *Image* element using two indexes for the two dimensions is not supported at the moment. +- A single element of a one-dimensional array attribute (Spectrum) can be extracted with a single index between square brackets (e.g. ```name/of/dev/attr[ind]```). +- A single element of a two-dimensional array attribute (Image) can be extracted with two indexes between square brackets (e.g. ```name/of/dev/attr[ind_row][ind_column]```). +- A one-dimensional array can be extracted from a two-dimensional array attribute (Image) with a single index between square brackets (e.g. ```name/of/dev/attr[ind_row]```). + +If any index exceeds actual dimensions of the array, the formula is evaluated to ERROR with an out of bounds exception. + +## Limitations + +- It is not possible to specify array constants (e.g. ```name/of/dev/attr > [val1,val2]```). +- It is not possible to use indexes on expressions (e.g. ```(any_expression)[ind]```). ## Unary operators and functions diff --git a/src/AlarmHandler.cpp b/src/AlarmHandler.cpp index 927e4da..8b50b96 100644 --- a/src/AlarmHandler.cpp +++ b/src/AlarmHandler.cpp @@ -3863,6 +3863,9 @@ void AlarmHandler::do_alarm(bei_t& e) { found->value = e.value; found->value_string = e.value_string; + found->read_size = e.read_size; + found->dim_x = e.dim_x; + found->dim_y = e.dim_y; found->quality = e.quality; //found->errors = e.errors; found->ex_reason = e.ex_reason; @@ -4525,7 +4528,7 @@ formula_res_t AlarmHandler::eval_formula(tree_parse_info_t tree, string &attr_va return res; } -formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values, int ev_ind) //throw (string &), std::out_of_range +formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values, vector<double> ev_ind) { ostringstream err; @@ -4702,56 +4705,65 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values DEBUG_STREAM << " node event" << string(i->value.begin(), i->value.end()) << endl; #endif formula_res_t ind; - if(i->children.size() != 2) + if(i->children.size() < 2) { err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children=" << i->children.size();; throw err.str(); } - if((i->children.begin()+1)->value.id() == formula_grammar::indexID) - ind = eval_expression(i->children.begin()+1, attr_values); //array index - else if((i->children.begin()+1)->value.id() == formula_grammar::propertyID) + size_t child_ind=0; + while((child_ind < i->children.size() -1) && ((i->children.begin()+child_ind+1)->value.id() == formula_grammar::indexID)) + { + formula_res_t ind_tmp; + ind_tmp = eval_expression(i->children.begin()+child_ind+1, attr_values); //array index + if(ind_tmp.value.size() == 1 && ind_tmp.value[0]>=0) + { + ind.value.push_back(ind_tmp.value[0]); + } + child_ind++; + } + if(child_ind+1 == i->children.size() -1 && (i->children.begin()+child_ind+1)->value.id() == formula_grammar::propertyID) { - if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".quality") + if(string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()) == ".quality") { formula_res_t res; res = eval_expression(i->children.begin(), attr_values); res.value = {(double)res.quality}; ostringstream temp_attr_val; - temp_attr_val << "\"" << res.attr_name << string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) << "\":[" <<print_vector(res.value) << "],"; + temp_attr_val << "\"" << res.attr_name << string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()) << "\":[" <<print_vector(res.value) << "],"; attr_values += temp_attr_val.str(); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event.quality -> " << print_vector(res.value) << endl; #endif return res; } - else if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".alarm") + else if(string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()) == ".alarm") { formula_res_t res; if(!ind.value.empty()) - res = eval_expression(i->children.begin(), attr_values, (int)ind.value[0]); + res = eval_expression(i->children.begin(), attr_values, ind.value); else res = eval_expression(i->children.begin(), attr_values); std::transform(res.value.begin(), res.value.end(), res.value.begin(), [](double n) { return (double)((n == _UNACK) || (n == _ACKED)); }); ostringstream temp_attr_val; - temp_attr_val << "\"" << res.attr_name << string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) << "\":[" <<print_vector(res.value) << "],"; + temp_attr_val << "\"" << res.attr_name << string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()) << "\":[" <<print_vector(res.value) << "],"; attr_values += temp_attr_val.str(); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event.alarm -> " << print_vector(res.value)<< endl; #endif return res; } - else if(string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) == ".normal") + else if(string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()) == ".normal") { formula_res_t res; if(!ind.value.empty()) - res = eval_expression(i->children.begin(), attr_values, (int)ind.value[0]); + res = eval_expression(i->children.begin(), attr_values, ind.value); else res = eval_expression(i->children.begin(), attr_values); std::transform(res.value.begin(), res.value.end(), res.value.begin(), [](double n) { return (double)((n == _NORM) || (n == _RTNUN)); }); ostringstream temp_attr_val; - temp_attr_val << "\"" << res.attr_name << string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()) << "\":[" <<print_vector(res.value) << "],"; + temp_attr_val << "\"" << res.attr_name << string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()) << "\":[" <<print_vector(res.value) << "],"; attr_values += temp_attr_val.str(); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node event.normal -> " << print_vector(res.value) << endl; @@ -4759,13 +4771,13 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values return res; } } - else + else if(child_ind+1 < i->children.size() -1)//unsupported more indexes/qualities { - err << "in node event_ID(" << string(i->value.begin(), i->value.end()) << ") children2 is not an index ->" << string((i->children.begin()+1)->value.begin(), (i->children.begin()+1)->value.end()); + err << "expecting indexes or properties after attribute name, found instead: "<< string((i->children.begin()+child_ind+1)->value.begin(), (i->children.begin()+child_ind+1)->value.end()); throw err.str(); } if(!ind.value.empty()) - return eval_expression(i->children.begin(), attr_values, (int)ind.value[0]); + return eval_expression(i->children.begin(), attr_values, ind.value); else return eval_expression(i->children.begin(), attr_values); } @@ -4792,6 +4804,8 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values err << "attribute " << string(i->value.begin(), i->value.end()) << " value not valid while evaluating formula"; formula_res_t res; res.valid = false; + res.dim_x = it->dim_x; + res.dim_y = it->dim_y; res.quality = it->quality; res.ex_reason = it->ex_reason; res.ex_desc = it->ex_desc; @@ -4816,6 +4830,8 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values err << "attribute " << string(i->value.begin(), i->value.end()) << " value not initialized while evaluating formula"; formula_res_t res; res.valid = false; + res.dim_x = it->dim_x; + res.dim_y = it->dim_y; res.quality = it->quality; res.ex_reason = it->ex_reason; res.ex_desc = it->ex_desc; @@ -4831,33 +4847,113 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values events->veclock.readerOut(); //throw err.str(); return res; - } + } + formula_res_t res; + res.valid = true; + res.dim_x = it->dim_x; + res.dim_y = it->dim_y; + res.quality = it->quality; + res.ex_reason = it->ex_reason; + res.ex_desc = it->ex_desc; + res.ex_origin = it->ex_origin; + res.attr_name = it->name; ostringstream temp_attr_val; if(it->value.size() > 0) { - if(ev_ind > 0) - temp_attr_val << "\"" << it->name << "[" << ev_ind << "]\":[" <<it->value.at(ev_ind) << "],";//throw std::out_of_range + if(!ev_ind.empty()) + { + size_t ev_ind_1d = ev_ind[0]; + temp_attr_val << "\"" << it->name; + for(auto ei : ev_ind) + { + temp_attr_val << "[" << ei << "]"; + } + temp_attr_val << "\":"; + if(ev_ind.size() ==1 && it->dim_y <=1)//single element of 1D array + { + res.dim_x = 1; + res.dim_y = 0; + if(ev_ind[0] >= it->value.size()) + { + err << "Requested element " << ev_ind[0] << " is out of bounds with dim=" << it->value.size(); + events->veclock.readerOut(); + DEBUG_STREAM << __func__ << ": " << err.str() << endl; + Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification) + (const char *)"OUT_OF_RANGE", + err.str(), + it->name); + } + res.value = {it->value.at(ev_ind[0])};//throw std::out_of_range + temp_attr_val << "[" << res.value[0] << "],"; + } + else if(ev_ind.size() == 1 && it->dim_y > 1)//single row of 2D array + { + res.dim_y = 0; + if(ev_ind[0] >= it->dim_y) + { + err << "Requested row " << ev_ind[0] << " is out of bounds with dim_y=" << it->dim_y; + events->veclock.readerOut(); + DEBUG_STREAM << __func__ << ": " << err.str() << endl; + Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification) + (const char *)"OUT_OF_RANGE", + err.str(), + it->name); + } + auto vstart = it->value.begin(); + auto vend = it->value.begin(); + advance(vstart,(int)(ev_ind[0] * (it->dim_x))); + advance(vend,(int)(ev_ind[0]+1)*it->dim_x); + res.value = value_t(vstart,vend); + temp_attr_val << "[" << print_vector(res.value) << "],"; + } + else if(ev_ind.size() == 2 && it->dim_y > 1)//single element of 2D array + { + res.dim_x = 1; + res.dim_y = 0; + if(ev_ind[0] >= it->dim_y) + { + err << "Requested row " << ev_ind[0] << " is out of bounds with dim_y=" << it->dim_y; + events->veclock.readerOut(); + DEBUG_STREAM << __func__ << ": " << err.str() << endl; + Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification) + (const char *)"OUT_OF_RANGE", + err.str(), + it->name); + } + if(ev_ind[1] >= it->dim_x) + { + err << "Requested column " << ev_ind[1] << " is out of bounds with dim_x=" << it->dim_x; + events->veclock.readerOut(); + DEBUG_STREAM << __func__ << ": " << err.str() << endl; + Tango::Except::throw_exception( //throw exception to have error not delayed otherwise it is subject to err_delay (delayed error notification) + (const char *)"OUT_OF_RANGE", + err.str(), + it->name); + } + res.value = {it->value.at(ev_ind[0]*it->dim_x + ev_ind[1])};//throw std::out_of_range + temp_attr_val << "[" <<res.value[0] << "],";//throw std::out_of_range + } + else //TODO N-DIMENSIONAL arrays + { + err << "UNSUPPORTED array indexes: " << ev_ind.size() << " indexes given, dim_x=" << it->dim_x << " dim_y=" << it->dim_y; + DEBUG_STREAM << __func__ << ": " << err.str() << endl; + events->veclock.readerOut(); + throw err.str(); + } + } else - temp_attr_val << "\"" << it->name << "\":[" <<print_vector(it->value) << "],"; + { + res.value = it->value; + temp_attr_val << "\"" << it->name << "\":[" <<print_vector(res.value) << "],"; + } } else temp_attr_val << "\"" << it->name << "\":[],"; attr_values += temp_attr_val.str(); - formula_res_t res; - res.valid = true; - res.quality = it->quality; - res.ex_reason = it->ex_reason; - res.ex_desc = it->ex_desc; - res.ex_origin = it->ex_origin; - res.attr_name = it->name; + events->veclock.readerOut(); #ifdef _DEBUG_FORMULA DEBUG_STREAM << " node name -> " << temp_attr_val.str() << " quality=" << res.quality << endl; -#endif - if(ev_ind >=0) - res.value = {(it->value.at(ev_ind))}; //throw std::out_of_range - else - res.value = it->value; - events->veclock.readerOut(); +#endif return res; } else @@ -4958,7 +5054,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); } - vectorUtils::applyVectorFunc(val_l1, val_l2,res.value, "Bitwise &", vectorUtils::fBitAnd); + vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y,val_l2,res_2.dim_x,res_2.dim_y,res.value,res.dim_x,res.dim_y, "Bitwise &", vectorUtils::fBitAnd); return res; } else if (*i->value.begin() == '|') @@ -4972,7 +5068,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); } - vectorUtils::applyVectorFunc(val_l1, val_l2,res.value, "Bitwise |", vectorUtils::fBitOr); + vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise |", vectorUtils::fBitOr); return res; } else if (*i->value.begin() == '^') @@ -4986,7 +5082,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); } - vectorUtils::applyVectorFunc(val_l1, val_l2,res.value, "Bitwise ^", vectorUtils::fBitXor); + vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise ^", vectorUtils::fBitXor); return res; } else @@ -5045,7 +5141,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); } - vectorUtils::applyVectorFunc(val_l1, val_l2,res.value, "Bitwise <<", vectorUtils::fBitShiftL); + vectorUtils::applyVectorFunc(val_l1, res_2.dim_x,res_2.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise <<", vectorUtils::fBitShiftL); return res; } else if (string(i->value.begin(), i->value.end()) == string(">>")) @@ -5059,7 +5155,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values res.ex_desc = res.combine_exception(res_1.ex_desc, res_2.ex_desc); res.ex_origin = res.combine_exception(res_1.ex_origin, res_2.ex_origin); } - vectorUtils::applyVectorFunc(val_l1, val_l2,res.value, "Bitwise >>", vectorUtils::fBitShiftR); + vectorUtils::applyVectorFunc(val_l1, res_1.dim_x,res_1.dim_y, val_l2,res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, "Bitwise >>", vectorUtils::fBitShiftR); return res; } else @@ -5106,6 +5202,8 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values if(it->ex_desc.length() > 0) err << " EX: '" << it->ex_desc << "'"; res.valid = false; + res.dim_x = it->dim_x; + res.dim_y = it->dim_y; res.quality = it->quality; res.ex_reason = it->ex_reason; res.ex_desc = it->ex_desc; @@ -5123,6 +5221,8 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values if(it->ex_desc.length() > 0) err << " EX: '" << it->ex_desc << "'"; res.valid = false; + res.dim_x = it->dim_x; + res.dim_y = it->dim_y; res.quality = it->quality; res.ex_reason = it->ex_reason; res.ex_desc = it->ex_desc; @@ -5138,6 +5238,8 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values temp_attr_val << "\"" << it->name << "\":\"" <<it->value_string << "\","; attr_values += temp_attr_val.str(); res.valid = true; + res.dim_x = it->dim_x; + res.dim_y = it->dim_y; res.quality = it->quality; res.ex_reason = it->ex_reason; res.ex_desc = it->ex_desc; @@ -5307,7 +5409,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values if (string(i->value.begin(), i->value.end()) == string("min")) { formula_res_t res; - vectorUtils::applyVectorFunc(res_1.value, res_2.value, res.value, string(i->value.begin(), i->value.end()), vectorUtils::fMin); + vectorUtils::applyVectorFunc(res_1.value, res_1.dim_x,res_1.dim_y, res_2.value, res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, string(i->value.begin(), i->value.end()), vectorUtils::fMin); res.valid = valid; res.quality = res.combine_quality(res_1.quality, res_2.quality); if(!res.valid) @@ -5321,7 +5423,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values else if (string(i->value.begin(), i->value.end()) == string("max")) { formula_res_t res; - vectorUtils::applyVectorFunc(res_1.value, res_2.value, res.value, string(i->value.begin(), i->value.end()), vectorUtils::fMax); + vectorUtils::applyVectorFunc(res_1.value, res_1.dim_x,res_1.dim_y, res_2.value, res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, string(i->value.begin(), i->value.end()), vectorUtils::fMax); res.valid = valid; res.quality = res.combine_quality(res_1.quality, res_2.quality); if(!res.valid) @@ -5335,7 +5437,7 @@ formula_res_t AlarmHandler::eval_expression(iter_t const& i, string &attr_values else if (string(i->value.begin(), i->value.end()) == string("pow")) { formula_res_t res; - vectorUtils::applyVectorFunc(res_1.value, res_2.value, res.value, string(i->value.begin(), i->value.end()), vectorUtils::fPow); + vectorUtils::applyVectorFunc(res_1.value, res_1.dim_x,res_1.dim_y, res_2.value, res_2.dim_x,res_2.dim_y, res.value,res.dim_x,res.dim_y, string(i->value.begin(), i->value.end()), vectorUtils::fPow); res.valid = valid; res.quality = res.combine_quality(res_1.quality, res_2.quality); if(!res.valid) diff --git a/src/AlarmHandler.h b/src/AlarmHandler.h index de47f24..d8b6007 100644 --- a/src/AlarmHandler.h +++ b/src/AlarmHandler.h @@ -607,7 +607,7 @@ private: formula_res_t eval_formula(tree_parse_info_t tree, string &attr_values); void find_event_formula(tree_parse_info_t tree, vector<string> &); - formula_res_t eval_expression(iter_t const& i, string &attr_values, int ev_ind=-1); //recursive tree node evaluation + formula_res_t eval_expression(iter_t const& i, string &attr_values, vector<double> ev_ind={}); //recursive tree node evaluation void eval_node_event(iter_t const& i, vector<string> & ev); //recursive tree node evaluation void prepare_alarm_attr(); //for read attribute alarm and push_change_event diff --git a/src/alarm_table.h b/src/alarm_table.h index 5d396bd..d3701ec 100644 --- a/src/alarm_table.h +++ b/src/alarm_table.h @@ -149,16 +149,29 @@ static double fAnd(double a, double b){ return (double)((bool)a && (bool)b);} static double fOr(double a, double b){ return (double)((bool)a || (bool)b);} template<class T > -static void applyVectorFunc(const vector<T> & v1, const vector<T> & v2, value_t &res, const string& origin, double (*func)(T, T)) +static void applyVectorFunc(const vector<T> & v1, long v1_x, long v1_y, const vector<T> & v2, long v2_x, long v2_y, value_t &res, long &res_x, long &res_y, const string& origin, double (*func)(T, T)) { if(v1.size() > 0 && v2.size() > 0 && (v1.size() == v2.size())) { + res_x = v1_x; + res_y = v1_y; + if(v1_x != v2_x || (v1_y != v2_y && (v1_y > 1 || v2_y > 1)))//dim_y 0 and 1 are the same + { + ostringstream o; + o << "Array sizes do not match: " << (v1_y ? v1_y : 1) << "x" << v1_x << " != " << (v2_y ? v2_y : 1) << "x" << v2_x; + Tango::Except::throw_exception( //throw exception to have error not delayed + "FORMULA_ERROR", + o.str(), + origin); + } res.resize(v1.size()); std::transform(v1.begin(), v1.end(), v2.begin(),res.begin(), [func](T a, T b) { return func(a, b); }); } else if(v2.size() == 1) { + res_x = v1_x; + res_y = v1_y; T b = v2[0]; res.resize(v1.size()); std::transform(v1.begin(), v1.end(), res.begin(), @@ -166,6 +179,8 @@ static void applyVectorFunc(const vector<T> & v1, const vector<T> & v2, value_t } else if(v1.size() == 1) { + res_x = v2_x; + res_y = v2_y; T a = v1[0]; res.resize(v2.size()); std::transform(v2.begin(), v2.end(), res.begin(), @@ -174,7 +189,7 @@ static void applyVectorFunc(const vector<T> & v1, const vector<T> & v2, value_t else if(v1.size() > 0 && v2.size() > 0) { ostringstream o; - o << "Array sizes do not match: " << v1.size() << "!=" <<v2.size(); + o << "Array sizes do not match: " << (v1_y ? v1_y : 1) << "x" << v1_x << " != " << (v2_y ? v2_y : 1) << "x" << v2_x; Tango::Except::throw_exception( //throw exception to have error not delayed "FORMULA_ERROR", o.str(), @@ -185,8 +200,10 @@ static void applyVectorFunc(const vector<T> & v1, const vector<T> & v2, value_t struct formula_res_t { - formula_res_t(){valid=false;quality=Tango::ATTR_VALID;ex_reason=string("");ex_desc=string("");ex_origin=string("");} + formula_res_t(){valid=false;quality=Tango::ATTR_VALID;ex_reason=string("");ex_desc=string("");ex_origin=string("");dim_x=0;dim_y=0;} value_t value; + long dim_x; + long dim_y; int quality; bool valid; string error; @@ -233,7 +250,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fEqual); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fEqual); return res; } formula_res_t operator!=(const formula_res_t& e) @@ -247,7 +264,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fDifferent); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fDifferent); return res; } formula_res_t operator<=(const formula_res_t& e) @@ -261,7 +278,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fLessEqual); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fLessEqual); return res; } formula_res_t operator>=(const formula_res_t& e) @@ -275,7 +292,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fGreaterEqual); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fGreaterEqual); return res; } formula_res_t operator<(const formula_res_t& e) @@ -289,7 +306,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fLess); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fLess); return res; } formula_res_t operator>(const formula_res_t& e) @@ -303,7 +320,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fGreater); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fGreater); return res; } formula_res_t operator||(const formula_res_t& e) @@ -325,7 +342,7 @@ struct formula_res_t } if(!(value.size() <= 1 && e.value.size() <= 1)) { - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fOr); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fOr); } return res; } @@ -348,7 +365,7 @@ struct formula_res_t } if(!(value.size() <= 1 && e.value.size() <= 1)) { - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fAnd); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fAnd); } return res; } @@ -363,7 +380,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fPlus); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fPlus); return res; } formula_res_t operator-(const formula_res_t& e) @@ -377,7 +394,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fMinus); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fMinus); return res; } formula_res_t operator*(const formula_res_t& e) @@ -391,7 +408,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fMult); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fMult); return res; } formula_res_t operator/(const formula_res_t& e) @@ -405,7 +422,7 @@ struct formula_res_t res.ex_desc = combine_exception(ex_desc, e.ex_desc); res.ex_origin = combine_exception(ex_origin, e.ex_origin); } - vectorUtils::applyVectorFunc(value,e.value,res.value,__func__,vectorUtils::fDiv); + vectorUtils::applyVectorFunc(value,dim_x,dim_y,e.value,e.dim_x,e.dim_y,res.value,res.dim_x,res.dim_y,__func__,vectorUtils::fDiv); return res; } formula_res_t operator!() diff --git a/src/event_table.cpp b/src/event_table.cpp index f52d904..2f9f977 100644 --- a/src/event_table.cpp +++ b/src/event_table.cpp @@ -1278,7 +1278,7 @@ void EventCallBack::push_event(Tango::EventData* ev) e.ev_name = ev->attr_name; #endif e.ts = ev->attr_value->time; - extract_values(ev->attr_value, e.value, e.value_string, e.type, e.read_size); + extract_values(ev->attr_value, e.value, e.value_string, e.type, e.read_size, e.dim_x, e.dim_y); } else { e.quality = Tango::ATTR_INVALID; #if 0//TANGO_VER >= 711 @@ -1341,7 +1341,7 @@ void EventCallBack::push_event(Tango::EventData* ev) static_cast<AlarmHandler_ns::AlarmHandler *>(mydev)->evlist.push_back(e); } /* push_event() */ -void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size) +void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size, long &dim_x, long &dim_y) { Tango::DevState stval; vector<Tango::DevState> v_st; @@ -1375,6 +1375,8 @@ void EventCallBack::extract_values(Tango::DeviceAttribute *attr_value, vector<do attr_r_dim.dim_y = 0; //attr_w_dim.dim_y = 0; } + dim_x = attr_r_dim.dim_x; + dim_y = attr_r_dim.dim_y; read_size = attr_r_dim.dim_x; if(attr_r_dim.dim_y > 1) read_size *= attr_r_dim.dim_y; diff --git a/src/event_table.h b/src/event_table.h index 764369b..21758e0 100644 --- a/src/event_table.h +++ b/src/event_table.h @@ -66,7 +66,8 @@ class event { int type, /* attribute data type */ read_size, /* attribute size of read part */ counter, /* molteplicita' */ - err_counter; /* molteplicita' errore */ + err_counter; /* molteplicita' errore */ + long dim_x, dim_y; alarm_list m_alarm; bool valid; //TODO: old bool first;//TODO: new @@ -116,6 +117,8 @@ typedef struct basic_event_info_s { string ex_origin; int type; int read_size; + long dim_x; + long dim_y; Tango::TimeVal ts; string msg; } bei_t; @@ -202,7 +205,7 @@ class EventCallBack : public Tango::CallBack, public Tango::LogAdapter ~EventCallBack(void); void push_event(Tango::EventData* ev); //void init(event_list* e); - void extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size); + void extract_values(Tango::DeviceAttribute *attr_value, vector<double> &val, string &val_string, int &type, int &read_size, long &dim_x, long &dim_y); private: //event_list* e_ptr; Tango::DeviceImpl *mydev; diff --git a/src/formula_grammar.h b/src/formula_grammar.h index 0aba5d0..8a83118 100644 --- a/src/formula_grammar.h +++ b/src/formula_grammar.h @@ -263,8 +263,8 @@ struct formula_grammar : public grammar<formula_grammar> event_ = name - >> !( (index) - | (property) + >> ( *(index)//0 or more indexex + >> !(property) //followed by 0 or 1 property ) ; -- GitLab