From cde6b7727b47c28e0a7a6213a44ad4136a7bf5d8 Mon Sep 17 00:00:00 2001 From: Martin Hierholzer <martin.hierholzer@desy.de> Date: Thu, 11 Jan 2018 15:51:58 +0100 Subject: [PATCH] Do not stop server (even through assert -> undefined behaviour without Debug flags!) when trying to create a string array. Instead the property is simply ignored and a warning is printed. --- src/CSAdapterEqFct.cc | 16 +++++++++++----- src/DoocsPVFactory.cc | 11 +++++++++-- 2 files changed, 20 insertions(+), 7 deletions(-) diff --git a/src/CSAdapterEqFct.cc b/src/CSAdapterEqFct.cc index 4914d6a..d968be4 100644 --- a/src/CSAdapterEqFct.cc +++ b/src/CSAdapterEqFct.cc @@ -6,22 +6,22 @@ namespace ChimeraTK{ bool CSAdapterEqFct::emptyLocationVariablesHandled = false; - + CSAdapterEqFct::CSAdapterEqFct(int fctCode, boost::shared_ptr<ControlSystemPVManager> const & controlSystemPVManager, boost::shared_ptr<DoocsUpdater> const & updater, std::string fctName ) // The second argument in EqFct has to be a pointer to string, and NULL pointer is // used when the name is coming from the config file. This interface is so ugly that - // I changed it to std::string and need the ?: trick to get a NULL pointer in + // I changed it to std::string and need the ?: trick to get a NULL pointer in // if the string is empty : EqFct ("NAME = CSAdapterEqFct", fctName.empty()?NULL:&fctName), controlSystemPVManager_(controlSystemPVManager), fctCode_(fctCode), updater_(updater){ - + registerProcessVariablesInDoocs(); } - + CSAdapterEqFct::~CSAdapterEqFct(){ //stop the updater thread before any of the process variables go out of scope updater_->stop(); @@ -43,7 +43,13 @@ namespace ChimeraTK{ doocsProperties_.reserve( mappingForThisLocation.size() ); for (auto & propertyDescrition : mappingForThisLocation){ - doocsProperties_.push_back( factory.create( propertyDescrition ) ); + try { + doocsProperties_.push_back( factory.create( propertyDescrition ) ); + } + catch(std::invalid_argument &e) { + std::cerr << "**** WARNING: Could not create property for variable '" << propertyDescrition->location << "/" << + propertyDescrition->name << "': " << e.what() << ". Skipping this property." << std::endl; + } } } diff --git a/src/DoocsPVFactory.cc b/src/DoocsPVFactory.cc index a248fdf..da483b3 100644 --- a/src/DoocsPVFactory.cc +++ b/src/DoocsPVFactory.cc @@ -170,8 +170,9 @@ namespace ChimeraTK { } else if (valueType == typeid(double)) { return typedCreateScalarOrArray<double, D_double, double, D_doublearray, double>(*processVariable, *autoPropertyDescription, DecoratorType::range_checking, ArrayDescription::DataType::Double); } else if (valueType == typeid(std::string)) { - //@todo FIXME returning scalar also for arrays. This should result in an error - return createDoocsScalar<std::string, D_string>(*autoPropertyDescription, DecoratorType::range_checking); + return typedCreateScalarOrArray<std::string, D_string, std::string, + std::nullptr_t, std::nullptr_t>(*processVariable, *autoPropertyDescription, + DecoratorType::range_checking, ArrayDescription::DataType::Auto); } else { throw std::invalid_argument("unsupported value type"); } @@ -194,6 +195,12 @@ namespace ChimeraTK { return doocsPV; } + // template specialisation for cases with no matching DOOCS array type (e.g. string) + template<> + boost::shared_ptr<D_fct> DoocsPVFactory::typedCreateDoocsArray<std::nullptr_t,std::nullptr_t>(ArrayDescription const &){ + throw std::invalid_argument("Type not supported as an array"); + } + boost::shared_ptr<D_fct> DoocsPVFactory::createDoocsArray( std::shared_ptr<ArrayDescription> const & arrayDescription){ if(arrayDescription->dataType == ArrayDescription::DataType::Auto){ // leave the desision which array to produce to the auto creation algorithm. We need it there anyway -- GitLab