From 0c5e2d965ef7a1e367a7a9547f826f69d97386f3 Mon Sep 17 00:00:00 2001
From: Markus FRANK <Markus.Frank@cern.ch>
Date: Wed, 2 Dec 2020 18:34:53 +0100
Subject: [PATCH] Enable conditional builds with scaled shapes and G4<10.3

---
 DDCore/include/DD4hep/DetectorData.h  |  4 ++-
 DDCore/include/DD4hep/Handle.h        |  4 +++
 DDCore/src/Handle.cpp                 | 36 ++++++++++++++++++++-------
 DDParsers/src/Evaluator/Evaluator.cpp |  9 +++++++
 4 files changed, 43 insertions(+), 10 deletions(-)

diff --git a/DDCore/include/DD4hep/DetectorData.h b/DDCore/include/DD4hep/DetectorData.h
index ff4fecd2a..abb135c3a 100644
--- a/DDCore/include/DD4hep/DetectorData.h
+++ b/DDCore/include/DD4hep/DetectorData.h
@@ -67,7 +67,9 @@ namespace dd4hep {
           std::pair<iterator, bool> r = this->emplace(n, e.ptr());
           if (!throw_on_doubles || r.second) {
             if (not r.second) {
-              printout(WARNING,"Detector","+++ Object '%s' is already defined and new one will be ignored", n.c_str());
+              printout(WARNING,"Detector",
+		       "+++ Object '%s' is already defined. New value will be ignored",
+		       n.c_str());
             }
             return;
           }
diff --git a/DDCore/include/DD4hep/Handle.h b/DDCore/include/DD4hep/Handle.h
index 7d69ff2ef..1ece25da3 100644
--- a/DDCore/include/DD4hep/Handle.h
+++ b/DDCore/include/DD4hep/Handle.h
@@ -39,8 +39,12 @@ namespace dd4hep {
   // Forward declarations
   class NamedObject;
 
+  /// Steer redefinition of variable re-definition during expression evaluation. returns old value
+  bool set_allow_variable_redefine(bool value);
+
   long num_object_validations();
   void increment_object_validations();
+
   /// Function tp print warning about deprecated factory usage. Used by Plugin mechanism.
   void warning_deprecated_xml_factory(const char* name);
 
diff --git a/DDCore/src/Handle.cpp b/DDCore/src/Handle.cpp
index 93f76a3f7..bd1663411 100644
--- a/DDCore/src/Handle.cpp
+++ b/DDCore/src/Handle.cpp
@@ -11,10 +11,12 @@
 //
 //==========================================================================
 
+#include "DD4hep/detail/Handle.inl"
 #include "DD4hep/InstanceCount.h"
 #include "DD4hep/Printout.h"
-#include "DD4hep/detail/Handle.inl"
 #include "Evaluator/Evaluator.h"
+
+/// C/C++ include files
 #include <iostream>
 #include <iomanip>
 #include <climits>
@@ -38,7 +40,10 @@ using namespace dd4hep;
 using namespace dd4hep::detail;
 
 namespace   {
+  /// Set true for backwards compatibility
+  static bool s_allow_variable_redefine = true;
 
+  ///
   void check_evaluation(const string& value, std::pair<int,double> res, stringstream& err)   {
     if ( res.first != tools::Evaluator::OK) {
       throw runtime_error("dd4hep: "+err.str()+" : value="+value+" [Evaluation error]");
@@ -48,6 +53,13 @@ namespace   {
 }
 
 namespace dd4hep  {
+
+  /// Steer redefinition of variable re-definition during expression evaluation. returns old value
+  bool set_allow_variable_redefine(bool value)    {
+    bool tmp = s_allow_variable_redefine;
+    s_allow_variable_redefine = value;
+    return tmp;
+  }
   
   std::pair<int, double> _toFloatingPoint(const string& value)   {
     stringstream err;
@@ -165,7 +177,7 @@ namespace dd4hep  {
     double val = _toDouble(left + "*" + right);
     if ( val >= 0 && val <= double(UCHAR_MAX) )
       return (unsigned char) (int)val;
-    except("_multiply<char>",
+    except("_multiply<unsigned char>",
            "Multiplication %e = %s * %s out of bounds for conversion to unsigned char.",
            val, left.c_str(), right.c_str());
     return 0;
@@ -175,7 +187,7 @@ namespace dd4hep  {
     double val = _toDouble(left + "*" + right);
     if ( val >= double(SHRT_MIN) && val <= double(SHRT_MAX) )
       return (short) val;
-    except("_multiply<char>",
+    except("_multiply<short>",
            "Multiplication %e = %s * %s out of bounds for conversion to short.",
            val, left.c_str(), right.c_str());
     return 0;
@@ -185,7 +197,7 @@ namespace dd4hep  {
     double val = _toDouble(left + "*" + right);
     if ( val >= 0 && val <= double(USHRT_MAX) )
       return (unsigned short)val;
-    except("_multiply<char>",
+    except("_multiply<unsigned short>",
            "Multiplication %e = %s * %s out of bounds for conversion to unsigned short.",
            val, left.c_str(), right.c_str());
     return 0;
@@ -226,6 +238,7 @@ namespace dd4hep  {
       return;
     }
     else  {
+      int status;
       stringstream err;
       string n = name, v = value;
       size_t idx = v.find("(int)");
@@ -239,12 +252,17 @@ namespace dd4hep  {
       auto result = eval.evaluate(v, err);
       check_evaluation(v, result, err);
       err.str("");
-      if ( eval.setVariable(n, result.second, err) != tools::Evaluator::OK ) {
+      status = eval.setVariable(n, result.second, err);
+      if ( status != tools::Evaluator::OK )   {
 	stringstream err_msg;
-	err_msg << "dd4hep: " << err.str() << " : value="
-		<< result.second
-		<< " [setVariable error]";
-	throw runtime_error(err_msg.str());
+	err_msg << "name=" << name << " value=" << value
+		<< "  " << err.str() << " [setVariable error]";
+	if ( status == tools::Evaluator::WARNING_EXISTING_VARIABLE )   {
+	  if ( s_allow_variable_redefine )
+	    printout(WARNING,"Evaluator","+++ Overwriting variable: "+err_msg.str());
+	  else
+	    except("Evaluator","+++ Overwriting variable: "+err_msg.str());
+	}
       }
     }
   }
diff --git a/DDParsers/src/Evaluator/Evaluator.cpp b/DDParsers/src/Evaluator/Evaluator.cpp
index 6f4155633..dec742531 100644
--- a/DDParsers/src/Evaluator/Evaluator.cpp
+++ b/DDParsers/src/Evaluator/Evaluator.cpp
@@ -671,6 +671,15 @@ void Evaluator::Object::print_error(std::ostream& os) const {
   static char prefix[] = "Evaluator::Object : ";
   const char* opt = (imp->thePosition ? imp->thePosition : "");
   switch (imp->theStatus) {
+  case WARNING_EXISTING_VARIABLE:
+    os << prefix << "existing variable";
+    return;
+  case WARNING_EXISTING_FUNCTION:
+    os << prefix << "existing function";
+    return;
+  case WARNING_BLANK_STRING:
+    os << prefix << "blank string detected";
+    return;
   case ERROR_NOT_A_NAME:
     os << prefix << "invalid name : " << opt;
     return;
-- 
GitLab