File indexing completed on 2025-01-30 09:17:43
0001 #include "DD4hep/DDTest.h"
0002 #include <exception>
0003 #include <iostream>
0004 #include <assert.h>
0005 #include <cmath>
0006 #include <array>
0007
0008 #include <atomic>
0009 #include <thread>
0010
0011 #include "Evaluator/Evaluator.h"
0012
0013
0014 using namespace std ;
0015 using namespace dd4hep ;
0016
0017
0018 static DDTest test( "Evaluator" ) ;
0019
0020 namespace {
0021 double foo() { return 8.0;}
0022 }
0023
0024
0025
0026 int main(int , char** ){
0027
0028 try{
0029
0030
0031
0032 test.log( "test Evaluator" );
0033 using namespace dd4hep::tools;
0034 Evaluator e;
0035 {
0036 auto r = e.evaluate("5.2");
0037 test( r.second , 5.2, " double value");
0038 test( r.first, Evaluator::OK, " status OK");
0039 }
0040
0041 {
0042 auto r = e.evaluate("4*m");
0043 test( r.second , 4, " double value in meters");
0044 test( r.first, Evaluator::OK, " status OK");
0045 }
0046
0047 {
0048 auto r = e.evaluate("4*cm");
0049 test( r.second , 0.04, " double value in cm");
0050 test( r.first, Evaluator::OK, " status OK");
0051 }
0052
0053 {
0054 auto r = e.evaluate("abs(-4)");
0055 test( r.second , 4., " call abs");
0056 test( r.first, Evaluator::OK, " status OK");
0057 }
0058
0059 {
0060 auto r = e.evaluate("min(7, 2)");
0061 test( r.second , 2., " call min");
0062 test( r.first, Evaluator::OK, " status OK");
0063 }
0064
0065 {
0066 auto r = e.evaluate("7_");
0067 test( r.first, Evaluator::ERROR_UNEXPECTED_SYMBOL, " status UNEXPECTED SYMBOL");
0068 }
0069
0070 {
0071 e.setVariable("myVar", 12);
0072 auto r = e.evaluate("myVar");
0073 test( r.second , 12., " use myVar variable");
0074 test( r.first, Evaluator::OK, " status OK");
0075 }
0076
0077 {
0078 e.setFunction("foo", foo);
0079 auto r = e.evaluate("foo()");
0080 test( r.second , foo(), " call new function foo");
0081 test( r.first, Evaluator::OK, " status OK");
0082 }
0083
0084 {
0085
0086 Evaluator e_cm(100.);
0087
0088 {
0089 auto r = e_cm.evaluate("4*m");
0090 test( r.second , 400, " double value in meters with cm as unit");
0091 test( r.first, Evaluator::OK, " status OK");
0092 }
0093
0094 {
0095 auto r = e_cm.evaluate("4*cm");
0096 test( r.second , 4, " double value in cm with cm as unit");
0097 test( r.first, Evaluator::OK, " status OK");
0098 }
0099 }
0100
0101 {
0102
0103 std::atomic<int> countDownToStart{2};
0104
0105 std::atomic<bool> success{true};
0106
0107 Evaluator e_threads;
0108
0109 std::array<std::string,100> nameExtensions;
0110 char extension[3];
0111 extension[2] = 0;
0112 for(char i = 0; i< 4;++i) {
0113 extension[1] = 97+i;
0114 for(char j = 0; j<25;++j) {
0115 extension[0]=97+j;
0116 nameExtensions[i*25+j] = std::string(extension,2);
0117 }
0118 }
0119
0120
0121 std::thread t1([&countDownToStart, &success, &e_threads, &nameExtensions]() {
0122 const std::string name("ta");
0123 --countDownToStart;
0124 while(countDownToStart != 0);
0125
0126 for(int i=0; i< 100; ++i) {
0127 std::string newName = name+nameExtensions[i];
0128 auto status = e_threads.setVariable(newName, i);
0129 if(status != Evaluator::OK) {
0130 success = false;
0131 std::cout <<"Failed to add variable "<<newName<<" "<<status<<std::endl;
0132 break;
0133 };
0134 auto r = e_threads.evaluate( newName+"*m");
0135 if(r.first != Evaluator::OK) {
0136 success = false;
0137 std::cout <<"Parser failure "<<r.first<<" for variable "<<newName<<std::endl;
0138 break;
0139 }
0140 if(r.second != i) {
0141 success = false;
0142 std::cout <<"Failed evaluation "<<i <<" != "<<r.second<<" for variable "<<newName<<std::endl;
0143 break;
0144 }
0145 }
0146
0147 }
0148 );
0149 #if 0
0150 std::thread t2([&countDownToStart, &success, &e_threads,&nameExtensions]()
0151 #endif
0152 std::thread t2([&countDownToStart]()
0153 {
0154 const std::string name("tb");
0155 --countDownToStart;
0156 while(countDownToStart != 0);
0157 return;
0158 #if 0
0159 Commented out to please Coverity:
0160 CID 1501200 (#1 of 1): Structurally dead code (UNREACHABLE)unreachable: This code cannot be reached:
0161
0162 for(int i=0; i< 100; ++i) {
0163 std::string newName = name+nameExtensions[i];
0164 e_threads.setVariable(newName, i);
0165 auto r = e_threads.evaluate( newName+"*m");
0166 if(r.first != Evaluator::OK) {
0167 success = false;
0168 std::cout <<"Parser failure "<<r.first<<" for variable "<<newName<<std::endl;
0169 break;
0170 }
0171 if(r.second != i) {
0172 success = false;
0173 std::cout <<"Failed evaluation "<<i <<" != "<<r.second<<" for variable "<<newName<<std::endl;
0174 break;
0175 }
0176 }
0177 #endif
0178 }
0179 );
0180
0181 t1.join();
0182 t2.join();
0183
0184 test(success.load(), " multi-thread test");
0185
0186 }
0187
0188
0189
0190
0191 } catch( exception &e ){
0192
0193
0194 test.log( e.what() );
0195 test.error( "exception occurred" );
0196 }
0197
0198 return 0;
0199 }
0200
0201