From 736d7b993d0506a4291c48bd513e48233284a7c7 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Thu, 9 Aug 2018 16:26:46 +0200 Subject: [PATCH] Make the expression evaluator understand variable names with namespaces --- DDCore/src/plugins/Compact2Objects.cpp | 6 ++ DDParsers/src/Evaluator/Evaluator.cpp | 4 +- examples/ClientTests/CMakeLists.txt | 10 +++ .../compact/NamespaceConstants.xml | 28 +++++++ .../src/TestConstantMultiplier.cpp | 76 +++++++++++++++++++ 5 files changed, 122 insertions(+), 2 deletions(-) create mode 100644 examples/ClientTests/compact/NamespaceConstants.xml create mode 100644 examples/ClientTests/src/TestConstantMultiplier.cpp diff --git a/DDCore/src/plugins/Compact2Objects.cpp b/DDCore/src/plugins/Compact2Objects.cpp index b83422f20..b4f862a1a 100644 --- a/DDCore/src/plugins/Compact2Objects.cpp +++ b/DDCore/src/plugins/Compact2Objects.cpp @@ -96,6 +96,7 @@ namespace { bool s_debug_elements = false; bool s_debug_materials = false; bool s_debug_segmentation = false; + bool s_debug_constants = false; } static Ref_t create_ConstantField(Detector& /* description */, xml_h e) { @@ -249,6 +250,7 @@ template <> void Converter<Debug>::operator()(xml_h e) const { else if ( nam.substr(0,6) == "readou" ) s_debug_readout = (0 != val); else if ( nam.substr(0,6) == "limits" ) s_debug_limits = (0 != val); else if ( nam.substr(0,6) == "segmen" ) s_debug_segmentation = (0 != val); + else if ( nam.substr(0,6) == "consta" ) s_debug_constants = (0 != val); } } @@ -287,6 +289,10 @@ template <> void Converter<Constant>::operator()(xml_h e) const { Constant c(nam, val, typ); _toDictionary(nam, val, typ); description.addConstant(c); + if ( s_debug_constants ) { + printout(ALWAYS, "Compact", + "++ Converting constant %-16s = %-32s [%s]", nam.c_str(), val.c_str(), typ.c_str()); + } return; } xml::DocumentHolder doc(xml::DocumentHandler().load(e, e.attr_value(_U(ref)))); diff --git a/DDParsers/src/Evaluator/Evaluator.cpp b/DDParsers/src/Evaluator/Evaluator.cpp index 3e00155d1..9a38df587 100644 --- a/DDParsers/src/Evaluator/Evaluator.cpp +++ b/DDParsers/src/Evaluator/Evaluator.cpp @@ -232,7 +232,7 @@ static int operand(pchar begin, pchar end, double & result, while(pointer <= end) { c = *pointer; - if (c != '_' && !isalnum(c)) break; + if ( !(c == '_' || c == ':') && !isalnum(c)) break; pointer++; } c = *pointer; @@ -572,7 +572,7 @@ static void setItem(const char * prefix, const char * name, } for(int i=0; i<n; i++) { char c = *(pointer+i); - if (c != '_' && !isalnum(c)) { + if ( !(c == '_' || c== ':') && !isalnum(c)) { s->theStatus = EVAL::ERROR_NOT_A_NAME; return; } diff --git a/examples/ClientTests/CMakeLists.txt b/examples/ClientTests/CMakeLists.txt index 845b9a7ef..d6f124cc7 100644 --- a/examples/ClientTests/CMakeLists.txt +++ b/examples/ClientTests/CMakeLists.txt @@ -31,6 +31,16 @@ dd4hep_install_dir( compact scripts ref DESTINATION ${ClientTestsEx_INSTALL} ) dd4hep_configure_scripts( ClientTests DEFAULT_SETUP WITH_TESTS) #--- Testing ------------------------------------------------------------ # +# Test namespaces for constants +dd4hep_add_test_reg( ClientTests_namespace_constants + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" + EXEC_ARGS geoPluginRun -input ${ClientTestsEx_INSTALL}/compact/NamespaceConstants.xml + -destroy -plugin DD4hep_VolumeDump -plugin DD4hep_TestConstantsMultiplier + REGEX_PASS "Constant: world_z = world::Z \\[number\\] -> 10\\*world_z = 1e\\+03" + REGEX_FAIL "Exception" + REGEX_FAIL "FAILED" + ) +# # Test JSON based parser dd4hep_add_test_reg( ClientTests_MiniTel_JSON_Dump COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_ClientTests.sh" diff --git a/examples/ClientTests/compact/NamespaceConstants.xml b/examples/ClientTests/compact/NamespaceConstants.xml new file mode 100644 index 000000000..61a87f033 --- /dev/null +++ b/examples/ClientTests/compact/NamespaceConstants.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8"?> +<lccdd xmlns:compact="http://www.lcsim.org/schemas/compact/1.0" + xmlns:xs="http://www.w3.org/2001/XMLSchema" + xs:noNamespaceSchemaLocation="http://www.lcsim.org/schemas/compact/1.0/compact.xsd"> + + <define> + <constant name="world_side" value="2*m"/> + <constant name="world:X" value="world_side/2"/> + <constant name="world:Y" value="world:X"/> + <constant name="world:Z" value="world:Y"/> + <constant name="world::Z" value="world:Y"/> + <constant name="world_x" value="world:X"/> + <constant name="world_y" value="world:Y"/> + <constant name="world_z" value="world::Z"/> + </define> + <debug> + <type name="constants" value="1"/> + </debug> + <includes> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/elements.xml"/> + <gdmlFile ref="${DD4hepINSTALL}/DDDetectors/compact/materials.xml"/> + </includes> + <!-- + <plugins> + <plugin name="DD4hep_TestConstantsMultiplier"/> + </plugins> + --> +</lccdd> diff --git a/examples/ClientTests/src/TestConstantMultiplier.cpp b/examples/ClientTests/src/TestConstantMultiplier.cpp new file mode 100644 index 000000000..b2e86f94a --- /dev/null +++ b/examples/ClientTests/src/TestConstantMultiplier.cpp @@ -0,0 +1,76 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== +/* + Plugin invocation: + ================== + This plugin behaves like a main program. + Invoke the plugin with something like this: + + geoPluginRun -destroy -plugin DD4hep_XML-In-Memory -input <file name> + +*/ +// Framework include files +#include "DD4hep/Printout.h" +#include "DD4hep/Factories.h" +#include "DD4hep/Detector.h" +#include "DD4hep/detail/ObjectsInterna.h" +#include <fstream> +#include <cerrno> + +using namespace std; +using namespace dd4hep; + +/// Plugin function: Test in memory XML parsing of a simple sub detector +/** + * Factory: DD4hep_XML-In-Memory + * + * Though there is a file name given, it is read FIRST and then parsed. + * Similar to a in memory XML string. + * + * \author M.Frank + * \version 1.0 + * \date 20/01/2018 + */ +static int multiply_constants (Detector& detector, int argc, char** argv) { + bool help = false; + for(int i=0; i<argc && argv[i]; ++i) { + if ( 0 == ::strncmp("-help",argv[i],4) ) + help = true; + else + help = true; + } + if ( help ) { + /// Help printout describing the basic command line interface + cout << + "Usage: -plugin <name> -arg [-arg] \n" + " name: factory name DD4hep_TestConstantsMultiplier \n" + "\tArguments given: " << arguments(argc,argv) << endl << flush; + ::exit(EINVAL); + } + const auto& constants = detector.constants(); + for(const auto e : constants) { + Constant c = e.second; + if ( c.dataType() == "number" ) { + try { + double res = _multiply(c.name(),10.0); + printout(INFO,"TestConstantsMultiplier","+++ Constant: %-16s = %-16s [%s] -> 10*%-16s = %9.3g", + c.name(), c->GetTitle(), c.dataType().c_str(), c.name(), res); + } + catch(...) { + } + } + } + return 1; +} + +DECLARE_APPLY(DD4hep_TestConstantsMultiplier,multiply_constants) -- GitLab