diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3852f91dd79770cc82fbfd1ea6cda6985d07de97 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,14 @@ +# Set up the project. +cmake_minimum_required( VERSION 3.1 ) +project( "GeoModelTools" VERSION 1.0.0 LANGUAGES CXX ) + +add_subdirectory(XMLParser) +add_subdirectory(JSONParser) +add_subdirectory(ExpressionEvaluator) + +install(EXPORT JSONParser-export FILE GeoModelTools-JSONParser.cmake DESTINATION lib/cmake/GeoModelTools) +install(EXPORT XMLParser-export FILE GeoModelTools-XMLParser.cmake DESTINATION lib/cmake/GeoModelTools) +install(EXPORT ExpressionEvaluator-export FILE GeoModelTools-ExpressionEvaluator.cmake DESTINATION lib/cmake/GeoModelTools) + +install(FILES cmake/GeoModelToolsConfig.cmake DESTINATION lib/cmake/GeoModelTools) + diff --git a/ExpressionEvaluator/CMakeLists.txt b/ExpressionEvaluator/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..2e8c273e2c4f3297ab8b98318154cc2704de7865 --- /dev/null +++ b/ExpressionEvaluator/CMakeLists.txt @@ -0,0 +1,54 @@ +cmake_minimum_required( VERSION 3.1 ) + +# Set up the project. +project( "ExpressionEvaluator" VERSION 1.0.0 LANGUAGES CXX ) + +# Set default build options. +set( CMAKE_BUILD_TYPE "Release" CACHE STRING "CMake build mode to use" ) +set( CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard used for the build" ) +set( CMAKE_CXX_EXTENSIONS FALSE CACHE BOOL "(Dis)allow using GNU extensions" ) + +# Use the GNU install directory names. +include( GNUInstallDirs ) + +find_package( GeoModelCore REQUIRED ) + +# Find the header and source files. +file( GLOB SOURCES src/*.cxx ) +file( GLOB HEADERS ExpressionEvaluator/*.h ) + +# Create the library. +add_library( ExpressionEvaluator SHARED ${HEADERS} ${SOURCES} ) +set_property( TARGET ExpressionEvaluator + PROPERTY PUBLIC_HEADER ${HEADERS} ) +target_link_libraries( ExpressionEvaluator PUBLIC GeoModelCore::GeoModelKernel ) +target_include_directories( ExpressionEvaluator SYSTEM PUBLIC ) +target_include_directories( ExpressionEvaluator PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> ) +source_group( "ExpressionEvaluator" FILES ${HEADERS} ) +source_group( "src" FILES ${SOURCES} ) + +# # Install the library. +# install( TARGETS ExpressionEvaluator +# EXPORT ExpressionEvaluator +# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +# PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ExpressionEvaluator ) + +# Install a CMake description of the project/library. +# install( EXPORT ExpressionEvaluator DESTINATION cmake ) + + +# new test GeoModelCore +install( TARGETS ExpressionEvaluator EXPORT ExpressionEvaluator-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ExpressionEvaluator ) +# +# Version the shared library. (Please update when cutting a new release!) +# +set(MYLIB_VERSION_MAJOR 1) +set(MYLIB_VERSION_MINOR 1) +set(MYLIB_VERSION_PATCH 0) +set(MYLIB_VERSION_STRING ${MYLIB_VERSION_MAJOR}.${MYLIB_VERSION_MINOR}.${MYLIB_VERSION_PATCH}) + +set_target_properties(ExpressionEvaluator PROPERTIES VERSION ${MYLIB_VERSION_STRING} SOVERSION ${MYLIB_VERSION_MAJOR}) + diff --git a/ExpressionEvaluator/ExpressionEvaluator/AGDDTokenizer.h b/ExpressionEvaluator/ExpressionEvaluator/AGDDTokenizer.h new file mode 100644 index 0000000000000000000000000000000000000000..d9e05d6dfb9dc60394dbf0043596c646097d4259 --- /dev/null +++ b/ExpressionEvaluator/ExpressionEvaluator/AGDDTokenizer.h @@ -0,0 +1,20 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef AGDDTokenizer_h +#define AGDDTokenizer_h +#include <string> +#include <vector> + +class AGDDTokenizer : public std::vector<std::string> { +public: + AGDDTokenizer(const std::string & sep, const std::string & input); + + +private: + +}; + + +#endif // AGDDTokenizer_h diff --git a/ExpressionEvaluator/ExpressionEvaluator/Evaluator.h b/ExpressionEvaluator/ExpressionEvaluator/Evaluator.h new file mode 100755 index 0000000000000000000000000000000000000000..d604a91ef9a7b4028e694911846ce938082bf3e0 --- /dev/null +++ b/ExpressionEvaluator/ExpressionEvaluator/Evaluator.h @@ -0,0 +1,264 @@ +// -*- C++ -*- +// $Id: Evaluator.h,v 1.2 2010/07/20 17:00:49 garren Exp $ +// --------------------------------------------------------------------------- + +#ifndef HEP_EVALUATOR_H +#define HEP_EVALUATOR_H + +#include <string> + +// namespace HepTool { + +/** + * Evaluator of arithmetic expressions with an extendable dictionary. + * Example: + * @code + * #include "CLHEP/Evaluator/Evaluator.h" + * HepTool::Evaluator eval; + * eval.setStdMath(); + * double res = eval.evaluate("sin(30*degree)"); + * if (eval.status() != HepTool::Evaluator::OK) eval.print_error(); + * @endcode + * + * @author Evgeni Chernyaev <Evgueni.Tcherniaev@cern.ch> + * @ingroup evaluator + */ +class Evaluator { + public: + + /** + * List of possible statuses. + * Status of the last operation can be obtained with status(). + * In case if status() is an ERROR the corresponding error message + * can be printed with print_error(). + * + * @see status + * @see error_position + * @see print_error + */ + enum { + OK, /**< Everything OK */ + WARNING_EXISTING_VARIABLE, /**< Redefinition of existing variable */ + WARNING_EXISTING_FUNCTION, /**< Redefinition of existing function */ + WARNING_BLANK_STRING, /**< Empty input string */ + ERROR_NOT_A_NAME, /**< Not allowed sysmbol in the name of variable or function */ + ERROR_SYNTAX_ERROR, /**< Systax error */ + ERROR_UNPAIRED_PARENTHESIS, /**< Unpaired parenthesis */ + ERROR_UNEXPECTED_SYMBOL, /**< Unexpected sysbol */ + ERROR_UNKNOWN_VARIABLE, /**< Non-existing variable */ + ERROR_UNKNOWN_FUNCTION, /**< Non-existing function */ + ERROR_EMPTY_PARAMETER, /**< Function call has empty parameter */ + ERROR_CALCULATION_ERROR /**< Error during calculation */ + }; + + /** + * Constructor. + */ + Evaluator(); + + /** + * Destructor. + */ + ~Evaluator(); + + /** + * Evaluates the arithmetic expression given as character string. + * The expression may consist of numbers, variables and functions + * separated by arithmetic (+, - , /, *, ^, **) and logical + * operators (==, !=, >, >=, <, <=, &&, ||). + * + * @param expression input expression. + * @return result of the evaluation. + * @see status + * @see error_position + * @see print_error + */ + double evaluate(const char * expression); + + /** + * Returns status of the last operation with the evaluator. + */ + int status() const; + + /** + * Returns position in the input string where the problem occured. + */ + int error_position() const; + + /** + * Prints error message if status() is an ERROR. + */ + void print_error() const; + /** + * get a string defining the error name + */ + std::string error_name() const; + + /** + * Adds to the dictionary a variable with given value. + * If a variable with such a name already exist in the dictionary, + * then status will be set to WARNING_EXISTING_VARIABLE. + * + * @param name name of the variable. + * @param value value assigned to the variable. + */ + void setVariable(const char * name, double value); + + /** + * Adds to the dictionary a variable with an arithmetic expression + * assigned to it. + * If a variable with such a name already exist in the dictionary, + * then status will be set to WARNING_EXISTING_VARIABLE. + * + * @param name name of the variable. + * @param expression arithmetic expression. + */ + void setVariable(const char * name, const char * expression); + + /** + * Adds to the dictionary a function without parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)()); + + /** + * Adds to the dictionary a function with one parameter. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double)); + + /** + * Adds to the dictionary a function with two parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double,double)); + + /** + * Adds to the dictionary a function with three parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, double (*fun)(double,double,double)); + + /** + * Adds to the dictionary a function with four parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, + double (*fun)(double,double,double,double)); + + /** + * Adds to the dictionary a function with five parameters. + * If such a function already exist in the dictionary, + * then status will be set to WARNING_EXISTING_FUNCTION. + * + * @param name function name. + * @param fun pointer to the real function in the user code. + */ + void setFunction(const char * name, + double (*fun)(double,double,double,double,double)); + + /** + * Finds the variable in the dictionary. + * + * @param name name of the variable. + * @return true if such a variable exists, false otherwise. + */ + bool findVariable(const char * name) const; + + /** + * Finds the function in the dictionary. + * + * @param name name of the function to be unset. + * @param npar number of parameters of the function. + * @return true if such a function exists, false otherwise. + */ + bool findFunction(const char * name, int npar) const; + + /** + * Removes the variable from the dictionary. + * + * @param name name of the variable. + */ + void removeVariable(const char * name); + + /** + * Removes the function from the dictionary. + * + * @param name name of the function to be unset. + * @param npar number of parameters of the function. + */ + void removeFunction(const char * name, int npar); + + /** + * Clear all settings. + */ + void clear(); + + /** + * Sets standard mathematical functions and constants. + */ + void setStdMath(); + + /** + * Sets system of units. Default is the SI system of units. + * To set the CGS (Centimeter-Gram-Second) system of units + * one should call: + * setSystemOfUnits(100., 1000., 1.0, 1.0, 1.0, 1.0, 1.0); + * + * To set system of units accepted in the GEANT4 simulation toolkit + * one should call: + * @code + * setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10, + * 1.0, 1.0, 1.0); + * @endcode + * + * The basic units in GEANT4 are: + * @code + * millimeter (millimeter = 1.) + * nanosecond (nanosecond = 1.) + * Mega electron Volt (MeV = 1.) + * positron charge (eplus = 1.) + * degree Kelvin (kelvin = 1.) + * the amount of substance (mole = 1.) + * luminous intensity (candela = 1.) + * radian (radian = 1.) + * steradian (steradian = 1.) + * @endcode + */ + void setSystemOfUnits(double meter = 1.0, + double kilogram = 1.0, + double second = 1.0, + double ampere = 1.0, + double kelvin = 1.0, + double mole = 1.0, + double candela = 1.0); + +private: + void * p; // private data + Evaluator(const Evaluator &); // copy constructor is not allowed + Evaluator & operator=(const Evaluator &); // assignment is not allowed +}; + +// } // namespace HepTool + +#endif /* HEP_EVALUATOR_H */ diff --git a/ExpressionEvaluator/ExpressionEvaluator/ExpressionEvaluator.h b/ExpressionEvaluator/ExpressionEvaluator/ExpressionEvaluator.h new file mode 100644 index 0000000000000000000000000000000000000000..b0667f86662ef25575ab29eab367a7e2f849a37c --- /dev/null +++ b/ExpressionEvaluator/ExpressionEvaluator/ExpressionEvaluator.h @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef EXPRESSION_EVALUATOR_H +#define EXPRESSION_EVALUATOR_H 1 + +#include "ExpressionEvaluator/Evaluator.h" + +#include <string> +#include <vector> +#include <map> + +typedef std::map< std::string, double > ConstantsTable; +typedef std::map< std::string, double > PhysicalConstantsTable; +typedef std::map< std::string, std::string > ExpressionsTable; + +class ExpressionEvaluator +{ +public: + ~ExpressionEvaluator(); + + static ExpressionEvaluator* GetEvaluator() { + static ExpressionEvaluator* eval=new ExpressionEvaluator(); + return eval; + } + bool RegisterConstant( std::string& c, double v ); + bool RegisterPhysConstant( std::string&, std::string, std::string ); + bool RegisterExpression( std::string& c, std::string v ); + bool RegisterArray( std::string& c, std::vector<double> v ); + bool RegisterVariable( const std::string& var_name, double value); + + double EvaluateString(const std::string& str); + bool is_delimiter(char c); + bool is_real_variable(const std::string& var_name); + double Eval( const std::string& expr ); + double Eval( const char* expr ); + + static std::string trim(const std::string); + static std::vector<std::string>& tokenize(const std::string&,const std::string&); + + void setFileCurrentlyParsed(std::string set) + { + m_fileCurrentlyParsed = set; + } + +private: + ExpressionEvaluator(); + Evaluator m_calc; + ConstantsTable m_CTable; + PhysicalConstantsTable m_PCTable; + std::string m_fileCurrentlyParsed; + std::vector<std::string> m_real_vars; +}; + +#endif // GDML_EXPRESSION_EVALUATOR_H + diff --git a/ExpressionEvaluator/ExpressionEvaluator/defs.h b/ExpressionEvaluator/ExpressionEvaluator/defs.h new file mode 100644 index 0000000000000000000000000000000000000000..c6a08009a67a0b13ff3865ba43f02b9bdf4f403a --- /dev/null +++ b/ExpressionEvaluator/ExpressionEvaluator/defs.h @@ -0,0 +1,26 @@ +/* Evaluator/defs.h Generated by cmake. */ + +#ifndef EVALUATOR_DEFS_H +#define EVALUATOR_DEFS_H + +/* Define to the address where bug reports for this package should be sent. */ +#ifndef CLHEP_EVALUATOR_BUGREPORT +#define CLHEP_EVALUATOR_BUGREPORT "http://proj-clhep.web.cern.ch/proj-clhep/" +#endif + +/* Define to the full name of this package. */ +#ifndef CLHEP_EVALUATOR_NAME +#define CLHEP_EVALUATOR_NAME "CLHEP Evaluator" +#endif + +/* Define to the full name and version of this package. */ +#ifndef CLHEP_EVALUATOR_STRING +#define CLHEP_EVALUATOR_STRING "CLHEP Evaluator 2.4.1.0" +#endif + +/* Define to the version of this package. */ +#ifndef CLHEP_EVALUATOR_VERSION +#define CLHEP_EVALUATOR_VERSION "2.4.1.0" +#endif + +#endif // EVALUATOR_DEFS_H diff --git a/ExpressionEvaluator/src/AGDDTokenizer.cxx b/ExpressionEvaluator/src/AGDDTokenizer.cxx new file mode 100644 index 0000000000000000000000000000000000000000..69fb8ff80a10902e45e0ca3739cf3c333cebdcee --- /dev/null +++ b/ExpressionEvaluator/src/AGDDTokenizer.cxx @@ -0,0 +1,15 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "ExpressionEvaluator/AGDDTokenizer.h" +#include <iostream> + +AGDDTokenizer::AGDDTokenizer(const std::string & sep, const std::string & input) { + std::string::size_type i=0, j=0; + while( (j=input.find(sep,i))!=std::string::npos) { + push_back(input.substr(i,j-i)); + i = j+sep.size(); + } + push_back(input.substr(i)); +} diff --git a/ExpressionEvaluator/src/Evaluator.cxx b/ExpressionEvaluator/src/Evaluator.cxx new file mode 100755 index 0000000000000000000000000000000000000000..85d782b56abb68df741364a4f8ab65d582876203 --- /dev/null +++ b/ExpressionEvaluator/src/Evaluator.cxx @@ -0,0 +1,794 @@ +// -*- C++ -*- +// $Id: Evaluator.cc,v 1.4 2010/07/20 17:00:49 garren Exp $ +// --------------------------------------------------------------------------- + +#include "ExpressionEvaluator/defs.h" +#include "ExpressionEvaluator/Evaluator.h" + +#include <iostream> +#include <sstream> +#include <cmath> // for std::pow() +#include "stack.src" +#include "string.src" +#include "hash_map.src" +#include <string.h> +#include <ctype.h> +#include <errno.h> +#include <stdlib.h> // for strtod() + +//--------------------------------------------------------------------------- +// Fix non ISO C++ compliant cast from pointer to function +// to void*, which is a pointer to an object +typedef void (*voidfuncptr)(); +struct Item { + enum { UNKNOWN, VARIABLE, EXPRESSION, FUNCTION } what; + double variable; + string expression; + // Fix non ISO C++ compliant cast from pointer to function + // to void*, which is a pointer to an object + //void *function; + voidfuncptr function; + + Item() : what(UNKNOWN), variable(0),expression(), function(0) {} + Item(double x) : what(VARIABLE), variable(x),expression(), function(0) {} + Item(string x) : what(EXPRESSION),variable(0),expression(x),function(0) {} + Item(voidfuncptr x) : what(FUNCTION), variable(0),expression(), function(x) {} +}; + +typedef char * pchar; +typedef hash_map<string,Item> dic_type; + +struct Struct { + dic_type theDictionary; + pchar theExpression; + pchar thePosition; + int theStatus; + double theResult; +}; + +//--------------------------------------------------------------------------- +// #define EVAL HepTool::Evaluator +#define EVAL Evaluator + +#define REMOVE_BLANKS \ +for(pointer=name;;pointer++) if (!isspace(*pointer)) break; \ +for(n=strlen(pointer);n>0;n--) if (!isspace(*(pointer+n-1))) break + +#define SKIP_BLANKS \ +for(;;pointer++) { \ + c = (pointer > end) ? '\0' : *pointer; \ + if (!isspace(c)) break; \ +} + +#define EVAL_EXIT(STATUS,POSITION) endp = POSITION; return STATUS +#define MAX_N_PAR 5 + +static const char sss[MAX_N_PAR+2] = "012345"; + +enum { ENDL, LBRA, OR, AND, EQ, NE, GE, GT, LE, LT, + PLUS, MINUS, UNARY_PLUS, UNARY_MINUS, MULT, DIV, POW, RBRA, VALUE }; + +static int engine(pchar, pchar, double &, pchar &, const dic_type &); + +static int variable(const string & name, double & result, + const dic_type & dictionary) +/*********************************************************************** + * * + * Name: variable Date: 03.10.00 * + * Author: Evgeni Chernyaev Revised: * + * * + * Function: Finds value of the variable. * + * This function is used by operand(). * + * * + * Parameters: * + * name - name of the variable. * + * result - value of the variable. * + * dictionary - dictionary of available variables and functions. * + * * + ***********************************************************************/ +{ + dic_type::const_iterator iter = dictionary.find(name); + if (iter == dictionary.end()) + return EVAL::ERROR_UNKNOWN_VARIABLE; + Item item = iter->second; + switch (item.what) { + case Item::VARIABLE: + result = item.variable; + return EVAL::OK; + case Item::EXPRESSION: { + pchar exp_begin = (char *)(item.expression.c_str()); + pchar exp_end = exp_begin + strlen(exp_begin) - 1; + if (engine(exp_begin, exp_end, result, exp_end, dictionary) == EVAL::OK) + return EVAL::OK; + } + default: + return EVAL::ERROR_CALCULATION_ERROR; + } +} + + + +#if defined __GNUC__ + #if __GNUC__ > 3 && __GNUC_MINOR__ > 6 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + #endif + #if __GNUC__ > 4 + #pragma GCC diagnostic push + #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" + #endif +#endif +static int function(const string & name, stack<double> & par, + double & result, const dic_type & dictionary) +/*********************************************************************** + * * + * Name: function Date: 03.10.00 * + * Author: Evgeni Chernyaev Revised: * + * * + * Function: Finds value of the function. * + * This function is used by operand(). * + * * + * Parameters: * + * name - name of the function. * + * par - stack of parameters. * + * result - value of the function. * + * dictionary - dictionary of available variables and functions. * + * * + ***********************************************************************/ +{ + int npar = par.size(); + if (npar > MAX_N_PAR) return EVAL::ERROR_UNKNOWN_FUNCTION; + + dic_type::const_iterator iter = dictionary.find(sss[npar]+name); + if (iter == dictionary.end()) return EVAL::ERROR_UNKNOWN_FUNCTION; + Item item = iter->second; + + double pp[MAX_N_PAR] = {0.0}; + for(int i=0; i<npar; i++) { pp[i] = par.top(); par.pop(); } + errno = 0; + if (item.function == 0) return EVAL::ERROR_CALCULATION_ERROR; + switch (npar) { + case 0: + result = ((double (*)())item.function)(); + break; + case 1: + result = ((double (*)(double))item.function)(pp[0]); + break; + case 2: + result = ((double (*)(double,double))item.function)(pp[1], pp[0]); + break; + case 3: + result = ((double (*)(double,double,double))item.function) + (pp[2],pp[1],pp[0]); + break; + case 4: + result = ((double (*)(double,double,double,double))item.function) + (pp[3],pp[2],pp[1],pp[0]); + break; + case 5: + result = ((double (*)(double,double,double,double,double))item.function) + (pp[4],pp[3],pp[2],pp[1],pp[0]); + break; + } + return (errno == 0) ? EVAL::OK : EVAL::ERROR_CALCULATION_ERROR; +} +#if defined __GNUC__ + #if __GNUC__ > 3 && __GNUC_MINOR__ > 6 + #pragma GCC diagnostic pop + #endif + #if __GNUC__ > 4 + #pragma GCC diagnostic pop + #endif +#endif + +static int operand(pchar begin, pchar end, double & result, + pchar & endp, const dic_type & dictionary) +/*********************************************************************** + * * + * Name: operand Date: 03.10.00 * + * Author: Evgeni Chernyaev Revised: * + * * + * Function: Finds value of the operand. The operand can be either * + * a number or a variable or a function. * + * This function is used by engine(). * + * * + * Parameters: * + * begin - pointer to the first character of the operand. * + * end - pointer to the last character of the character string. * + * result - value of the operand. * + * endp - pointer to the character where the evaluation stoped. * + * dictionary - dictionary of available variables and functions. * + * * + ***********************************************************************/ +{ + pchar pointer = begin; + int EVAL_STATUS; + char c; + + // G E T N U M B E R + + if (!isalpha(*pointer)) { + errno = 0; + result = strtod(pointer, (char **)(&pointer)); + if (errno == 0) { + EVAL_EXIT( EVAL::OK, --pointer ); + }else{ + EVAL_EXIT( EVAL::ERROR_CALCULATION_ERROR, begin ); + } + } + + // G E T N A M E + + while(pointer <= end) { + c = *pointer; + if (c != '_' && !isalnum(c)) break; + pointer++; + } + c = *pointer; + *pointer = '\0'; + string name(begin); + *pointer = c; + + // G E T V A R I A B L E + + result = 0.0; + SKIP_BLANKS; + if (c != '(') { + EVAL_STATUS = variable(name, result, dictionary); + EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? --pointer : begin); + } + + // G E T F U N C T I O N + + stack<pchar> pos; // position stack + stack<double> par; // parameter stack + double value; + pchar par_begin = pointer+1, par_end; + + for(;;pointer++) { + c = (pointer > end) ? '\0' : *pointer; + switch (c) { + case '\0': + EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pos.top() ); + case '(': + pos.push(pointer); break; + case ',': + if (pos.size() == 1) { + par_end = pointer-1; + EVAL_STATUS = engine(par_begin, par_end, value, par_end, dictionary); + if (EVAL_STATUS == EVAL::WARNING_BLANK_STRING) + { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); } + if (EVAL_STATUS != EVAL::OK) + { EVAL_EXIT( EVAL_STATUS, par_end ); } + par.push(value); + par_begin = pointer + 1; + } + break; + case ')': + if (pos.size() > 1) { + pos.pop(); + break; + }else{ + par_end = pointer-1; + EVAL_STATUS = engine(par_begin, par_end, value, par_end, dictionary); + switch (EVAL_STATUS) { + case EVAL::OK: + par.push(value); + break; + case EVAL::WARNING_BLANK_STRING: + if (par.size() != 0) + { EVAL_EXIT( EVAL::ERROR_EMPTY_PARAMETER, --par_end ); } + break; + default: + EVAL_EXIT( EVAL_STATUS, par_end ); + } + EVAL_STATUS = function(name, par, result, dictionary); + EVAL_EXIT( EVAL_STATUS, (EVAL_STATUS == EVAL::OK) ? pointer : begin); + } + } + } +} + +/*********************************************************************** + * * + * Name: maker Date: 28.09.00 * + * Author: Evgeni Chernyaev Revised: * + * * + * Function: Executes basic arithmetic operations on values in the top * + * of the stack. Result is placed back into the stack. * + * This function is used by engine(). * + * * + * Parameters: * + * op - code of the operation. * + * val - stack of values. * + * * + ***********************************************************************/ +static int maker(int op, stack<double> & val) +{ + if (val.size() < 2) return EVAL::ERROR_SYNTAX_ERROR; + double val2 = val.top(); val.pop(); + double val1 = val.top(); + switch (op) { + case OR: // operator || + val.top() = (val1 || val2) ? 1. : 0.; + return EVAL::OK; + case AND: // operator && + val.top() = (val1 && val2) ? 1. : 0.; + return EVAL::OK; + case EQ: // operator == + val.top() = (val1 == val2) ? 1. : 0.; + return EVAL::OK; + case NE: // operator != + val.top() = (val1 != val2) ? 1. : 0.; + return EVAL::OK; + case GE: // operator >= + val.top() = (val1 >= val2) ? 1. : 0.; + return EVAL::OK; + case GT: // operator > + val.top() = (val1 > val2) ? 1. : 0.; + return EVAL::OK; + case LE: // operator <= + val.top() = (val1 <= val2) ? 1. : 0.; + return EVAL::OK; + case LT: // operator < + val.top() = (val1 < val2) ? 1. : 0.; + return EVAL::OK; + case PLUS: // operator '+' + val.top() = val1 + val2; + return EVAL::OK; + case MINUS: // operator '-' + val.top() = val1 - val2; + return EVAL::OK; + case MULT: // operator '*' + val.top() = val1 * val2; + return EVAL::OK; + case DIV: // operator '/' + if (val2 == 0.0) return EVAL::ERROR_CALCULATION_ERROR; + val.top() = val1 / val2; + return EVAL::OK; + case POW: // operator '^' (or '**') + errno = 0; + val.top() = std::pow(val1,val2); + if (errno == 0) return EVAL::OK; + case UNARY_PLUS: // unary operator '+' + val.top() = val1 + val2; // val1 is zero + return EVAL::OK; + case UNARY_MINUS: // unary operator '-' + val.top() = val1 - val2; // val1 is zero + return EVAL::OK; + default: + return EVAL::ERROR_CALCULATION_ERROR; + } +} + +/*********************************************************************** + * * + * Name: engine Date: 28.09.00 * + * Author: Evgeni Chernyaev Revised: * + * * + * Function: Evaluates arithmetic expression. * + * * + * Parameters: * + * begin - pointer to the character string with expression. * + * end - pointer to the end of the character string (it is needed * + * for recursive call of engine(), when there is no '\0'). * + * result - result of the evaluation. * + * endp - pointer to the character where the evaluation stoped. * + * dictionary - dictionary of available variables and functions. * + * * + ***********************************************************************/ +static int engine(pchar begin, pchar end, double & result, + pchar & endp, const dic_type & dictionary) +{ + enum SyntaxTableEntry { + SyntaxError = 0, + NumberVariableOrFunction = 1, + UnaryPlusOrMinus = 2, + AnyOperator = 3 + }; + static const int SyntaxTable[19][19] = { + //E ( || && == != >= > <= < + - u+ u- * / ^ ) V - current token + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // E - previous + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // ( token + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // || + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // && + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // == + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // != + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // >= + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // > + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // <= + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // < + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // + + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // - + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // unary + + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // unary - + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // * + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // / + { 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 2, 2, 0, 0, 0, 0, 1 }, // ^ + { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 }, // ) + { 3, 0, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 0 } // V = {.,N,C} + }; + enum ActionTableEntry { + UnbalancedParentheses = -1, + ExpressionCompleted = 0, + HigherPrecedenceOperator = 1, + SamePrecedenceOperator = 2, + CloseProcessedParenthesesOrExpression = 3, + LowerPrecedenceOperator = 4 + }; + static const int ActionTable[17][18] = { + //E ( || && == != >= > <= < + - u+ u- * / ^ ) - current operator + { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,-1 }, // E - top operator + {-1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3 }, // ( in stack + { 4, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // || + { 4, 1, 4, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // && + { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // == + { 4, 1, 4, 4, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4 }, // != + { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // >= + { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // > + { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // <= + { 4, 1, 4, 4, 4, 4, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 4 }, // < + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 }, // + + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 1, 1, 1, 1, 1, 4 }, // - + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 }, // unary + + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 1, 4 }, // unary - + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 }, // * + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 2, 2, 1, 4 }, // / + { 4, 1, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 1, 1, 4, 4, 4, 4 } // ^ + }; + + stack<int> op; // operator stack + stack<pchar> pos; // position stack + stack<double> val; // value stack + double value; + pchar pointer = begin; + int iWhat, iCur, iPrev = 0, iTop, EVAL_STATUS; + char c; + + op.push(0); pos.push(pointer); // push EOL to the stack + SKIP_BLANKS; + if (c == '\0') { EVAL_EXIT( EVAL::WARNING_BLANK_STRING, begin ); } + for(;;pointer++) { + + // N E X T T O K E N + + c = (pointer > end) ? '\0' : *pointer; + if (isspace(c)) continue; // skip space, tab etc. + switch (c) { + case '\0': iCur = ENDL; break; + case '(': iCur = LBRA; break; + case '|': + if (*(pointer+1) == '|') { + pointer++; iCur = OR; break; + }else{ + EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); + } + case '&': + if (*(pointer+1) == '&') { + pointer++; iCur = AND; break; + }else{ + EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); + } + case '=': + if (*(pointer+1) == '=') { + pointer++; iCur = EQ; break; + }else{ + EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); + } + case '!': + if (*(pointer+1) == '=') { + pointer++; iCur = NE; break; + }else{ + EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); + } + case '>': + if (*(pointer+1) == '=') { pointer++; iCur = GE; } else { iCur = GT; } + break; + case '<': + if (*(pointer+1) == '=') { pointer++; iCur = LE; } else { iCur = LT; } + break; + case '+': iCur = PLUS; break; + case '-': iCur = MINUS; break; + case '*': + if (*(pointer+1) == '*') { pointer++; iCur = POW; }else{ iCur = MULT; } + break; + case '/': iCur = DIV; break; + case '^': iCur = POW; break; + case ')': iCur = RBRA; break; + default: + if (c == '.' || isalnum(c)) { + iCur = VALUE; break; + }else{ + EVAL_EXIT( EVAL::ERROR_UNEXPECTED_SYMBOL, pointer ); + } + } + + // S Y N T A X A N A L I S Y S + + iWhat = SyntaxTable[iPrev][iCur]; + iPrev = iCur; + switch (iWhat) { + case 0: // syntax error + EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); + case 1: // operand: number, variable, function + EVAL_STATUS = operand(pointer, end, value, pointer, dictionary); + if (EVAL_STATUS != EVAL::OK) { EVAL_EXIT( EVAL_STATUS, pointer ); } + val.push(value); + continue; + case 2: // unary + or unary - + val.push(0.0); + if (iCur == PLUS) iCur = UNARY_PLUS; + if (iCur == MINUS) iCur = UNARY_MINUS; + // Note that for syntax purposes, ordinary + or - are fine. + // Thus iPrev need not change when we encounter a unary minus or plus. + case 3: default: // next operator + break; + } + + // N E X T O P E R A T O R + + for(;;) { + if (op.size() == 0) { EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); } + iTop = op.top(); + switch (ActionTable[iTop][iCur]) { + case -1: // syntax error + if (op.size() > 1) pointer = pos.top(); + EVAL_EXIT( EVAL::ERROR_UNPAIRED_PARENTHESIS, pointer ); + case 0: // last operation (assignment) + if (val.size() == 1) { + result = val.top(); + EVAL_EXIT( EVAL::OK, pointer ); + }else{ + EVAL_EXIT( EVAL::ERROR_SYNTAX_ERROR, pointer ); + } + case 1: // push current operator in stack + op.push(iCur); pos.push(pointer); + break; + case 2: // execute top operator + EVAL_STATUS = maker(iTop, val); // put current operator in stack + if (EVAL_STATUS != EVAL::OK) { + EVAL_EXIT( EVAL_STATUS, pos.top() ); + } + op.top() = iCur; pos.top() = pointer; + break; + case 3: // delete '(' from stack + op.pop(); pos.pop(); + break; + case 4: default: // execute top operator and + EVAL_STATUS = maker(iTop, val); // delete it from stack + if (EVAL_STATUS != EVAL::OK) { // repete with the same iCur + EVAL_EXIT( EVAL_STATUS, pos.top() ); + } + op.pop(); pos.pop(); + continue; + } + break; + } + } +} + +//--------------------------------------------------------------------------- +static void setItem(const char * prefix, const char * name, + const Item & item, Struct * s) { + + if (name == 0 || *name == '\0') { + s->theStatus = EVAL::ERROR_NOT_A_NAME; + return; + } + + // R E M O V E L E A D I N G A N D T R A I L I N G S P A C E S + + const char * pointer; int n; REMOVE_BLANKS; + + // C H E C K N A M E + + if (n == 0) { + s->theStatus = EVAL::ERROR_NOT_A_NAME; + return; + } + for(int i=0; i<n; i++) { + char c = *(pointer+i); + if (c != '_' && !isalnum(c)) { + s->theStatus = EVAL::ERROR_NOT_A_NAME; + return; + } + } + + // A D D I T E M T O T H E D I C T I O N A R Y + + string item_name = prefix + string(pointer,n); + dic_type::iterator iter = (s->theDictionary).find(item_name); + if (iter != (s->theDictionary).end()) { + iter->second = item; + if (item_name == name) { + s->theStatus = EVAL::WARNING_EXISTING_VARIABLE; + }else{ + s->theStatus = EVAL::WARNING_EXISTING_FUNCTION; + } + }else{ + (s->theDictionary)[item_name] = item; + s->theStatus = EVAL::OK; + } +} + +//--------------------------------------------------------------------------- +// namespace HepTool { + +//--------------------------------------------------------------------------- +Evaluator::Evaluator() { + Struct * s = new Struct(); + p = (void *) s; + s->theExpression = 0; + s->thePosition = 0; + s->theStatus = OK; + s->theResult = 0.0; +} + +//--------------------------------------------------------------------------- +Evaluator::~Evaluator() { + delete (Struct *)(p); +} + +//--------------------------------------------------------------------------- +double Evaluator::evaluate(const char * expression) { + Struct * s = (Struct *)(p); + if (s->theExpression != 0) { delete[] s->theExpression; } + s->theExpression = 0; + s->thePosition = 0; + s->theStatus = WARNING_BLANK_STRING; + s->theResult = 0.0; + if (expression != 0) { + s->theExpression = new char[strlen(expression)+1]; + strcpy(s->theExpression, expression); + s->theStatus = engine(s->theExpression, + s->theExpression+strlen(expression)-1, + s->theResult, + s->thePosition, + s->theDictionary); + } + return s->theResult; +} + +//--------------------------------------------------------------------------- +int Evaluator::status() const { + return ((Struct *)(p))->theStatus; +} + +//--------------------------------------------------------------------------- +int Evaluator::error_position() const { + return ((Struct *)(p))->thePosition - ((Struct *)(p))->theExpression; +} + +//--------------------------------------------------------------------------- +void Evaluator::print_error() const { + Struct * s = (Struct *) p; + if(s->theStatus != OK) { + std::cerr << error_name() << std::endl; + } + return; +} + +//--------------------------------------------------------------------------- +std::string Evaluator::error_name() const +{ + char prefix[] = "Evaluator : "; + std::ostringstream errn; + Struct * s = (Struct *) p; + switch (s->theStatus) { + case ERROR_NOT_A_NAME: + errn << prefix << "invalid name"; + break; + case ERROR_SYNTAX_ERROR: + errn << prefix << "syntax error"; + break; + case ERROR_UNPAIRED_PARENTHESIS: + errn << prefix << "unpaired parenthesis"; + break; + case ERROR_UNEXPECTED_SYMBOL: + errn << prefix << "unexpected symbol"; + break; + case ERROR_UNKNOWN_VARIABLE: + errn << prefix << "unknown variable"; + break; + case ERROR_UNKNOWN_FUNCTION: + errn << prefix << "unknown function"; + break; + case ERROR_EMPTY_PARAMETER: + errn << prefix << "empty parameter in function call"; + break; + case ERROR_CALCULATION_ERROR: + errn << prefix << "calculation error"; + break; + default: + errn << " "; + } + return errn.str(); +} + +//--------------------------------------------------------------------------- +void Evaluator::setVariable(const char * name, double value) +{ setItem("", name, Item(value), (Struct *)p); } + +void Evaluator::setVariable(const char * name, const char * expression) +{ setItem("", name, Item(expression), (Struct *)p); } + +//--------------------------------------------------------------------------- +// Fix non ISO C++ compliant cast from pointer to function +// to void*, which is a pointer to an object +void Evaluator::setFunction(const char * name, + double (*fun)()) +{ setItem("0", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } + +void Evaluator::setFunction(const char * name, + double (*fun)(double)) +{ setItem("1", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } + +void Evaluator::setFunction(const char * name, + double (*fun)(double,double)) +{ setItem("2", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } + +void Evaluator::setFunction(const char * name, + double (*fun)(double,double,double)) +{ setItem("3", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } + +void Evaluator::setFunction(const char * name, + double (*fun)(double,double,double,double)) +{ setItem("4", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } + +void Evaluator::setFunction(const char * name, + double (*fun)(double,double,double,double,double)) +{ setItem("5", name, Item(reinterpret_cast<voidfuncptr>(fun)), (Struct *)p); } + +//--------------------------------------------------------------------------- +bool Evaluator::findVariable(const char * name) const { + if (name == 0 || *name == '\0') return false; + const char * pointer; int n; REMOVE_BLANKS; + if (n == 0) return false; + Struct * s = (Struct *)(p); + return + ((s->theDictionary).find(string(pointer,n)) == (s->theDictionary).end()) ? + false : true; +} + +//--------------------------------------------------------------------------- +bool Evaluator::findFunction(const char * name, int npar) const { + if (name == 0 || *name == '\0') return false; + if (npar < 0 || npar > MAX_N_PAR) return false; + const char * pointer; int n; REMOVE_BLANKS; + if (n == 0) return false; + Struct * s = (Struct *)(p); + return ((s->theDictionary).find(sss[npar]+string(pointer,n)) == + (s->theDictionary).end()) ? false : true; +} + +//--------------------------------------------------------------------------- +void Evaluator::removeVariable(const char * name) { + if (name == 0 || *name == '\0') return; + const char * pointer; int n; REMOVE_BLANKS; + if (n == 0) return; + Struct * s = (Struct *)(p); + (s->theDictionary).erase(string(pointer,n)); +} + +//--------------------------------------------------------------------------- +void Evaluator::removeFunction(const char * name, int npar) { + if (name == 0 || *name == '\0') return; + if (npar < 0 || npar > MAX_N_PAR) return; + const char * pointer; int n; REMOVE_BLANKS; + if (n == 0) return; + Struct * s = (Struct *)(p); + (s->theDictionary).erase(sss[npar]+string(pointer,n)); +} + +//--------------------------------------------------------------------------- +void Evaluator::clear() { + Struct * s = (Struct *) p; + s->theDictionary.clear(); + s->theExpression = 0; + s->thePosition = 0; + s->theStatus = OK; + s->theResult = 0.0; +} + +//--------------------------------------------------------------------------- +// } // namespace HepTool diff --git a/ExpressionEvaluator/src/ExpressionEvaluator.cxx b/ExpressionEvaluator/src/ExpressionEvaluator.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b49e0efd6d7ad22a67b7c3abfe94dbc67406ca35 --- /dev/null +++ b/ExpressionEvaluator/src/ExpressionEvaluator.cxx @@ -0,0 +1,328 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +// +#include "ExpressionEvaluator/Evaluator.h" +#include "ExpressionEvaluator/ExpressionEvaluator.h" +#include "ExpressionEvaluator/AGDDTokenizer.h" +#include "GeoModelKernel/Units.h" +#include <string> +#include <vector> +#include <cstdlib> +#include <cctype> +#include <cstring> +#include <iostream> +#include <sstream> +#include <algorithm> + +ExpressionEvaluator::ExpressionEvaluator() +{ + m_calc.clear(); + m_calc.setStdMath(); // set standard constants and functions + //m_calc.setSystemOfUnits(); // set SI units + // Set Geant4 system of units + m_calc.setSystemOfUnits(1.e+3, 1./1.60217733e-25, 1.e+9, 1./1.60217733e-10,1.0, 1.0, 1.0); + m_fileCurrentlyParsed = ""; +} + +ExpressionEvaluator::~ExpressionEvaluator() +{ + m_CTable.clear(); + m_PCTable.clear(); + m_calc.clear(); +} + +bool ExpressionEvaluator::RegisterConstant( std::string& c, double v ) +{ + double value = v; + + if( m_calc.status() != Evaluator::OK ) + { + std::cerr << "Expression evaluator:: Error registering constant " << c << std::endl; + m_calc.print_error(); + std::cout << std::endl; + return false; + } + + //RegisterVariable( c->get_name(), c->get_value() ); + RegisterVariable( c, value ); + return true; +} +bool ExpressionEvaluator::RegisterArray( std::string& c, std::vector<double> v) +{ + for(unsigned int i=0; i<v.size(); i++) + { + double value = v[i]; + std::stringstream ss; + std::string index; + ss << i; + ss >> index; + std::string name = c+"_"+index+"_"; +// std::cout << "setting variable: " << name << " with value: " << value << std::endl; + RegisterVariable( name, value ); + } + return true; +} + +bool ExpressionEvaluator::RegisterVariable( const std::string& var_name, double value) +{ + m_real_vars.push_back(var_name); + m_calc.setVariable( var_name.c_str(), value ); + return true; +} + +bool ExpressionEvaluator::is_real_variable(const std::string& var_name) +{ + + std::vector<std::string>::iterator start = m_real_vars.begin(); + std::vector<std::string>::iterator end = m_real_vars.end(); + std::vector<std::string>::iterator iter; + + iter = find(start, end, var_name); + + if (iter == end) + { + return false; + } + else + { + return true; + } +} + +bool ExpressionEvaluator::is_delimiter(char c) +{ + if(strchr(" ()|&=!><+-%*/^", c) || c==9 || c==0 || c=='\r' || c=='\n' || c=='\t' || c=='\0' || isspace(c)) return true; + else return false; +} + +double ExpressionEvaluator::EvaluateString(const std::string& str) +{ + std::string str_mod = str; +// if(m_fileCurrentlyParsed != "") +// { + const char* c_str_mod = str.c_str(); //string to be modified with file namespace! + std::vector<int> variable_ends; //variable names to be changed + int cur_variable_end = 0; + while(*c_str_mod) + { + if(is_delimiter(*c_str_mod) || isdigit(*c_str_mod)) + { + c_str_mod++; + cur_variable_end++; + } + else if(isalpha(*c_str_mod)) + { + char variable[80]; + char* token; + token = variable; + *token = '\0'; + while(!is_delimiter(*c_str_mod)) + { + *token=*c_str_mod; + token++; + c_str_mod++; + cur_variable_end++; + } + *token = '\0'; + std::string variable_to_check = variable; + if(is_real_variable(variable_to_check)) + { + variable_ends.push_back(cur_variable_end); + } + } + else + { + c_str_mod++; + cur_variable_end++; + } +// }// variable ends stored in vector + std::string::size_type shift = 0; + std::string::size_type ns_length = m_fileCurrentlyParsed.size(); + for(unsigned int i=0; i<variable_ends.size(); i++) + { + str_mod.insert(shift+variable_ends[i],m_fileCurrentlyParsed); + shift += ns_length; + } + } + double result = m_calc.evaluate( str_mod.c_str() ); + return result; +} +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ +/*********************************************************************************************************/ + + +bool ExpressionEvaluator::RegisterPhysConstant( std::string& c, std::string value, std::string unit ) +{ + std::string expr = value; + expr += "*("; + expr += unit; + expr += ")"; + + //std::cout << "Expression evaluator:: evaluating string: " << expr << std::endl; + + double dvalue = EvaluateString( expr ); +// double unit_value = EvaluateString( unit ); + + if( m_calc.status() != Evaluator::OK ) + { + std::cerr << "Expression evaluator:: Error registering quantity " + << c << std::endl; + m_calc.print_error(); + std::cout << std::endl; + return false; + } + + //RegisterVariable( physc->get_name(), expr ); + RegisterVariable( c, dvalue ); + return true; +} + +bool ExpressionEvaluator::RegisterExpression( std::string& name, std::string text ) +{ + std::string expr = "("; + expr += text; + expr += ")"; + double value = EvaluateString( expr ); + + if( m_calc.status() != Evaluator::OK ) + { + std::cerr << "Expression evaluator:: Error registering expression " << name << std::endl; + m_calc.print_error(); + std::cout << std::endl; + return false; + } + + //RegisterVariable( e->get_name(), e->get_text() ); + RegisterVariable( name, value ); + return true; +} + +double ExpressionEvaluator::Eval( const std::string& expr ) +{ + return Eval( expr.c_str() ); +} + +double ExpressionEvaluator::Eval( const char* expr_mod ) +{ + + std::string expr = expr_mod; + std::string::size_type start_index = 0; + std::string::size_type end_index = 0; + while(true) + { + start_index = expr.find('[', start_index); +// std::cout<<"*** start_index "<<start_index<<" "<<expr<<std::endl; + if(start_index == std::string::npos) break; +// std::cout << " start index "<<start_index<<std::endl; + std::string::size_type boundary_index = expr.find(']', start_index); + expr.replace(start_index,1,1,'_'); + end_index = expr.find(',', start_index); + if(end_index != std::string::npos && end_index < boundary_index) + { + start_index++; + std::string var1 = expr.substr(start_index, end_index-start_index); + double eval1 = EvaluateString( var1 ); + //std::cout<<"Evaluated "<<var1<<" to: "<<eval1<<std::endl; + std::stringstream ss1; + std::string str1; + ss1 << eval1; + ss1 >> str1; + expr.replace(start_index, end_index-start_index, str1, 0, str1.size()); + } + else + { + end_index = boundary_index; +// std::cout << " end index "<<end_index<<std::endl; + if(end_index != std::string::npos) + { + start_index++; + std::string var1 = expr.substr(start_index, end_index-start_index); + double eval1 = EvaluateString( var1 ); + //std::cout<<"Evaluated "<<var1<<" to: "<<eval1<<std::endl; + std::stringstream ss1; + std::string str1; + ss1 << eval1; + ss1 >> str1; + expr.replace(start_index, end_index-start_index, str1, 0, str1.size()); +// std::cout <<" str1 "<<str1<<std::endl; + } + } + } + start_index = 0; + end_index = 0; + while(true) + { + start_index = expr.find(',', start_index); + if(start_index == std::string::npos) break; + expr.replace(start_index,1,1,'_'); + end_index = expr.find(']', start_index); + start_index++; + std::string var2 = expr.substr(start_index, end_index-start_index); + double eval2 = EvaluateString( var2 ); + //std::cout<<"Evaluated "<<var2<<" to: "<<eval2<<std::endl; + std::stringstream ss2; + std::string str2; + ss2 << eval2; + ss2 >> str2; + expr.replace(start_index, end_index-start_index, str2, 0, str2.size()); + } + start_index = 0; + end_index = 0; + while(true) + { + start_index = expr.find(']', start_index); + if(start_index == std::string::npos) break; + expr.replace(start_index,1,1,'_'); + } +// std::cout<<"***************** "<<expr<<std::endl; + double result = EvaluateString( expr ); + if( m_calc.status() != Evaluator::OK ) + { + std::cerr << expr << std::endl; + //std::cerr << "------"; + for (int i=0; i<m_calc.error_position(); i++) + { + std::cerr << "-"; + } + std::cerr << "^\a" << std::endl; + m_calc.print_error(); + std::cerr << std::endl; + } + return result; +} + +std::string ExpressionEvaluator::trim (const std::string s) +//------------------------------------------------------------- +{ + static const std::string null_string; + if (s.size () == 0) return (s); + static std::string temp = ""; + temp=s; + std::string::size_type i; + i = temp.find_first_not_of (' '); + if (i == std::string::npos) return (null_string); +// There is at least 1 non blank character in s. + if (i > 0) + { + temp = temp.substr (i); + } + i = temp.find_last_not_of (' '); + if (i < temp.size ()) + { + temp = temp.substr (0, i + 1); + } + return (temp); +} + +std::vector<std::string>& ExpressionEvaluator::tokenize(const std::string& sep,const std::string& expr) +{ + static std::vector<std::string> tempvect; + tempvect.clear(); + AGDDTokenizer aa(sep,expr); + for (unsigned int i=0;i<aa.size();i++) tempvect.push_back(trim(aa[i])); + return tempvect; +} diff --git a/ExpressionEvaluator/src/hash_map.src b/ExpressionEvaluator/src/hash_map.src new file mode 100755 index 0000000000000000000000000000000000000000..c6855ed19b01f0c2c2bbf336da54a708aa3561a8 --- /dev/null +++ b/ExpressionEvaluator/src/hash_map.src @@ -0,0 +1,203 @@ +// -*- C++ -*- +// $Id: hash_map.src,v 1.1.1.1 2003/07/15 20:15:05 garren Exp $ +// --------------------------------------------------------------------------- + +#ifdef DEBUG_MODE +#include <iostream> +#endif + +#ifndef HEP_HASH_MAP_SRC +#define HEP_HASH_MAP_SRC + +#include <string.h> +#include <utility> +#include "string.src" + +/* + * Simplified hash_map class. + * It provides only basic functions of the standard <hash_map> and + * is intended to be used as a replacement of the standard class where + * full functionality of <hash_map> is not required, but it is essential + * to have highly portable and effective code. + * + * This file should be used exclusively inside *.cc files. + * Usage inside header files can result to a clash with standard <hash_map>. + * + * @author Evgeni Chernyaev <Evgueni.Tcherniaev@cern.ch> + */ +template<class K, class T> +class hash_map { +public: + struct Entry { // Hash_map entry + std::pair<const K,T> data; + Entry* next; + Entry(K k, T v, Entry* n) : data(k,v), next(n) {} + }; + + class hash_map_iterator { // Hash_map iterator + Entry* entry; + public: + hash_map_iterator() : entry(0) {} + hash_map_iterator(Entry & e) : entry(&e) {} + std::pair<const K,T> & operator * () const { return entry->data; } + std::pair<const K,T> * operator ->() const { return &(operator*()); } + bool operator==(hash_map_iterator i) const { + return (entry == i.entry); + } + bool operator!=(hash_map_iterator i) const { + return (entry != i.entry); + } + }; + +public: + typedef unsigned int size_type; + typedef std::pair<const K,T> value_type; + typedef hash_map_iterator iterator; + typedef hash_map_iterator const_iterator; + +private: + Entry** table; // Hash table: pointers to entries + size_type cur_size; // Number of entries + size_type max_size; // Bucket_count - current size of the table + float max_load; // Keep (n) <= (max_size * max_load) + float grow; // When necessary, resize(max_size * grow) + const T default_value; // Default value used by [] + + size_type hash(const char * key) const { + size_type res = 0; + while(*key) { res = res*31 + *key++; } + return res; + } + + size_type hash(const string & key) const { + return hash(key.c_str()); + } + + bool eq(const char * a, const char * b) const { + return (strcmp(a, b) == 0); + } + + bool eq(const string & a, const string & b) const { + return (a == b); + } + +public: + + // Constructor. + hash_map(const T & dv = T(), size_type n = 107) + : table(0), cur_size(0), max_size(0), default_value(dv) + { + set_load(); + resize(n); + } + + // Destructor. + ~hash_map() { + for(size_type i=0; i<max_size; i++) { + Entry* n = table[i]; + while(n) { Entry* p = n; n = p->next; delete p; } + } + delete [] table; + } + + // Sets load and grow parameters. + void set_load(float m = 0.7, float g = 1.7) { max_load = m; grow = g; } + + // Returns number of elements. + size_type size() const { return cur_size; } + + // Returns size of the hash table. + size_type bucket_count() const { return max_size; } + + // Resizes the hash table. + void resize(size_type s) { + if (s <= max_size) return; + Entry** tmp = table; + table = new Entry* [s]; + for (size_type k=0; k<s; k++) table[k] = 0; + for (size_type i=0; i<max_size; i++) { + Entry* n = tmp[i]; + while(n) { + Entry* p = n; + n = p->next; + size_type ii = hash(p->data.first) % s; + p->next = table[ii]; + table[ii] = p; + } + } + max_size = s; + delete [] tmp; + } + + // Subscripting. + T & operator[](const K & key) { + size_type i = hash(key) % max_size; + for (Entry* p=table[hash(key) % max_size]; p; p=p->next) { + if (eq(key,p->data.first)) return p->data.second; + } + if (cur_size++ >= max_size*max_load) { + resize(size_type(max_size*grow)); + i = hash(key) % max_size; + } + table[i] = new Entry(key, default_value, table[i]); + return table[i]->data.second; + } + + // Finds element with given key. + iterator find(const K & key) const { + size_type i = hash(key) % max_size; + for (Entry* p=table[i]; p; p=p->next) { + if (eq(key,p->data.first)) return iterator(*p); + } + return end(); + } + + // Erases element with given key. + size_type erase(const K & key) { + size_type i = hash(key) % max_size; + Entry* p = table[i]; + if (p == 0) return 0; + if (eq(key,p->data.first)) { + table[i] = p->next; delete p; cur_size--; return 1; + } + Entry** pp = &table[i]; + for (p=p->next; p; p=p->next) { + if (eq(key,p->data.first)) { + *pp = p->next; delete p; cur_size--; return 1; + }else{ + pp = &(p->next); + } + } + return 0; + } + + // Clears the hash table. + void clear() { + for(size_type i=0; i<max_size; i++) { + for (Entry* p=table[i]; p;) { + Entry* pp = p; p = p->next; delete pp; + } + table[i] = 0; + } + cur_size = 0; + } + + // Returns end iterator. + iterator end() const { return iterator(); } + +#ifdef DEBUG_MODE + // Prints content of the hash table. + void print() { + std::cout << endl; + for(size_type i=0; i<max_size; i++) { + for (Entry* p=table[i]; p; p=p->next) { + std::cout + << '"' << p->data.first << '"' << " " << p->data.second + << std::endl; + } + } + } +#endif +}; + +#endif /* HEP_HASH_MAP_SRC */ diff --git a/ExpressionEvaluator/src/setStdMath.cxx b/ExpressionEvaluator/src/setStdMath.cxx new file mode 100755 index 0000000000000000000000000000000000000000..79d1a6655d272492e25bd6f3b42c2928d8b9a6b4 --- /dev/null +++ b/ExpressionEvaluator/src/setStdMath.cxx @@ -0,0 +1,65 @@ +// -*- C++ -*- +// $Id: setStdMath.cc,v 1.2 2003/08/13 20:00:10 garren Exp $ +// ---------------------------------------------------------------------- + +#include "ExpressionEvaluator/defs.h" +#include "ExpressionEvaluator/Evaluator.h" + +#include <cmath> // for sqrt and pow + +static double eval_abs (double a) { return (a < 0) ? -a : a; } +static double eval_min (double a, double b) { return (a < b) ? a : b; } +static double eval_max (double a, double b) { return (a > b) ? a : b; } +static double eval_sqrt (double a) { return std::sqrt(a); } +static double eval_pow (double a, double b) { return std::pow(a,b); } +static double eval_sin (double a) { return std::sin(a); } +static double eval_cos (double a) { return std::cos(a); } +static double eval_tan (double a) { return std::tan(a); } +static double eval_asin (double a) { return std::asin(a); } +static double eval_acos (double a) { return std::acos(a); } +static double eval_atan (double a) { return std::atan(a); } +static double eval_atan2(double a, double b) { return std::atan2(a,b); } +static double eval_sinh (double a) { return std::sinh(a); } +static double eval_cosh (double a) { return std::cosh(a); } +static double eval_tanh (double a) { return std::tanh(a); } +static double eval_exp (double a) { return std::exp(a); } +static double eval_log (double a) { return std::log(a); } +static double eval_log10(double a) { return std::log10(a); } + +//namespace HepTool { + +void Evaluator::setStdMath() { + + // S E T S T A N D A R D C O N S T A N T S + + setVariable("pi", 3.14159265358979323846); + setVariable("e", 2.7182818284590452354); + setVariable("gamma", 0.577215664901532861); + setVariable("radian", 1.0); + setVariable("rad", 1.0); + setVariable("degree", 3.14159265358979323846/180.); + setVariable("deg", 3.14159265358979323846/180.); + + // S E T S T A N D A R D F U N C T I O N S + + setFunction("abs", eval_abs); + setFunction("min", eval_min); + setFunction("max", eval_max); + setFunction("sqrt", eval_sqrt); + setFunction("pow", eval_pow); + setFunction("sin", eval_sin); + setFunction("cos", eval_cos); + setFunction("tan", eval_tan); + setFunction("asin", eval_asin); + setFunction("acos", eval_acos); + setFunction("atan", eval_atan); + setFunction("atan2", eval_atan2); + setFunction("sinh", eval_sinh); + setFunction("cosh", eval_cosh); + setFunction("tanh", eval_tanh); + setFunction("exp", eval_exp); + setFunction("log", eval_log); + setFunction("log10", eval_log10); +} + +// } // namespace HepTool diff --git a/ExpressionEvaluator/src/setSystemOfUnits.cxx b/ExpressionEvaluator/src/setSystemOfUnits.cxx new file mode 100644 index 0000000000000000000000000000000000000000..31cc811db74c60114b3777ab081d3533721cc264 --- /dev/null +++ b/ExpressionEvaluator/src/setSystemOfUnits.cxx @@ -0,0 +1,411 @@ +// -*- C++ -*- +// $Id:$ +// ---------------------------------------------------------------------- + +#include "ExpressionEvaluator/defs.h" +#include "ExpressionEvaluator/Evaluator.h" + +// namespace HepTool { + +void Evaluator::setSystemOfUnits(double meter, + double kilogram, + double second, + double ampere, + double kelvin, + double mole, + double candela) +{ + const double kilo_ = 1.e+03; // chilioi (Greek) "thousand" + const double mega_ = 1.e+06; // megas (Greek) "large" + const double giga_ = 1.e+09; // gigas (Greek) "giant" + const double tera_ = 1.e+12; // teras (Greek) "monster" + const double peta_ = 1.e+15; // pente (Greek) "five" + + const double deci_ = 1.e-01; // decimus (Latin) "tenth" + const double centi_ = 1.e-02; // centum (Latin) "hundred" + const double milli_ = 1.e-03; // mille (Latin) "thousand" + const double micro_ = 1.e-06; // micro (Latin) or mikros (Greek) "small" + const double nano_ = 1.e-09; // nanus (Latin) or nanos (Greek) "dwarf" + const double pico_ = 1.e-12; // pico (Spanish) "bit" + + // ====================================================================== + // + // Base (default) SI units + // for the basic measurable quantities (dimensions): + // + // ====================================================================== + + // Length + // metrum (Latin) and metron (Greek) "measure" + const double m = meter; + setVariable("meter", m); + setVariable("metre", m); + setVariable("m", m); + + // Mass + const double kg = kilogram; + setVariable("kilogram", kg); + setVariable("kg", kg); + + // Time + // minuta secundam (Latin) "second small one" + const double s = second; + setVariable("second", s); + setVariable("s", s); + + // Current + // --- honors Andre-Marie Ampere (1775-1836) of France + const double A = ampere; + setVariable("ampere", A); + setVariable("amp", A); + setVariable("A", A); + + // Temperature + // --- honors William Thomson, 1st Baron Lord Kelvin (1824-1907) of England + const double K = kelvin; + setVariable("kelvin", K); + setVariable("K", K); + + // Amount of substance + const double mol = mole; + setVariable("mole", mol); + setVariable("mol", mol); + + // Luminous intensity + const double cd = candela; + setVariable("candela", cd); + setVariable("cd", cd); + + // ====================================================================== + // + // Supplementary SI units having special symbols: + // + // ====================================================================== + + // Plane angle + const double rad = 1.; + setVariable("radian", rad); + setVariable("rad", rad); + setVariable("milliradian", milli_ * rad); + setVariable("mrad", milli_ * rad); + + const double pi = 3.14159265358979323846; + const double deg = rad*pi/180.; + setVariable("degree", deg); + setVariable("deg", deg); + + // Solid angle + const double sr = 1.; + setVariable("steradian", sr); + setVariable("sr", sr); + + // ====================================================================== + // + // Derived SI units having special symbols: + // + // ====================================================================== + + // Frequency + // --- honors Heinrich Rudolf Hertz (1857-1894) of Germany + const double Hz = 1./s; + setVariable("hertz", Hz); + setVariable("Hz", Hz); + + // Force + // --- honors Sir Isaac Newton (1642-1727) of England + const double N = m * kg / (s*s); + setVariable("newton", N); + setVariable("N", N); + + // Pressure + // --- honors Blaise Pascal (1623-1662) of France + const double Pa = N / (m*m); + setVariable("pascal", Pa); + setVariable("Pa", Pa); + + const double atm = 101325. * Pa; + setVariable("atmosphere", atm); + setVariable("atm", atm); + + const double bar = 100000*Pa; + setVariable("bar", bar); + + // Energy + // --- honors James Prescott Joule (1818-1889) of England + const double J = N * m; + setVariable("joule", J); + setVariable("J", J); + + // Power + // --- honors James Watt (1736-1819) of Scotland + const double W = J / s; + setVariable("watt", W); + setVariable("W", W); + + // Electric charge + // --- honors Charles-Augustin de Coulomb (1736-1806) of France + const double C = A * s; + setVariable("coulomb", C); + setVariable("C", C); + + // Electric potential + // --- honors Count Alessandro Volta (1745-1827) of Italy + const double V = J / C; + setVariable("volt", V); + setVariable("V", V); + + // Electric resistance + // --- honors Georg Simon Ohm (1787-1854) of Germany + const double ohm = V / A; + setVariable("ohm", ohm); + + // Electric conductance + // --- honors Ernst Werner von Siemens (1816-1892) or + // his brother Sir William (Karl Wilhelm von) Siemens (1823-1883) + // of Germany (England) + const double S = 1./ ohm; + setVariable("siemens", S); + setVariable("S", S); + + // Electric capacitance + // --- honors Michael Faraday (1791-1867) of England + const double F = C / V; + setVariable("farad", F); + setVariable("F", F); + + // Magnetic flux density + // --- honors Nikola Tesla (1856-1943) of Croatia (United States) + const double T = V * s / (m*m); + setVariable("tesla", T); + setVariable("T", T); + + // --- honors Karl Friedrich Gauss (1777-1855) of Germany + const double Gs = 1.e-4*T; + setVariable("gauss", Gs); + setVariable("Gs", Gs); + + // Magnetic flux + // --- honors Wilhelm Eduard Weber (1804-1891) of Germany + const double Wb = V * s; + setVariable("weber", Wb); + setVariable("Wb", Wb); + + // Inductance + // --- honors Joseph Henry (1797-1878) of the United States + const double H = Wb / A; + setVariable("henry", H); + setVariable("H", H); + + // Luminous flux + const double lm = cd * sr; + setVariable("lumen", lm); + setVariable("lm", lm); + + // Illuminace + const double lx = lm / (m*m); + setVariable("lux", lx); + setVariable("lx", lx); + + // Radioactivity + // --- honors Antoine-Henri Becquerel (1852-1908) of France + const double Bq = 1./s; + setVariable("becquerel", Bq); + setVariable("Bq", Bq); + setVariable("kilobecquerel", kilo_ * Bq); + setVariable("kBq", kilo_ * Bq); + setVariable("megabecquerel", mega_ * Bq); + setVariable("MBq", mega_ * Bq); + setVariable("gigabecquerel", giga_ * Bq); + setVariable("GBq", giga_ * Bq); + + // --- honors Pierre Curie (1859-1906) of France + // and Marie Sklodowska Curie (1867-1934) of Poland + setVariable("curie", 3.7e+10 * Bq); + setVariable("Ci", 3.7e+10 * Bq); + setVariable("millicurie", milli_ * 3.7e+10 * Bq); + setVariable("mCi", milli_ * 3.7e+10 * Bq); + setVariable("microcurie", micro_ * 3.7e+10 * Bq); + setVariable("uCi", micro_ * 3.7e+10 * Bq); + + // Specific energy + // --- honors Louis Harold Gray, F.R.S. (1905-1965) of England + const double Gy = J / kg; + setVariable("gray", Gy); + setVariable("Gy", Gy); + setVariable("kilogray", kilo_ * Gy); + setVariable("milligray", milli_ * Gy); + setVariable("microgray", micro_ * Gy); + + // Dose equivalent + const double Sv = J / kg; + setVariable("sievert", Sv); + setVariable("Sv", Sv); + + // ====================================================================== + // + // Selected units: + // + // ====================================================================== + + // Length + + const double mm = milli_ * m; + setVariable("millimeter", mm); + setVariable("mm", mm); + + const double cm = centi_ * m; + setVariable("centimeter", cm); + setVariable("cm", cm); + + setVariable("decimeter", deci_ * m); + + const double km = kilo_ * m; + setVariable("kilometer", km); + setVariable("km", km); + + setVariable("micrometer", micro_ * m); + setVariable("micron", micro_ * m); + setVariable("nanometer", nano_ * m); + + // --- honors Anders Jonas Angstrom (1814-1874) of Sweden + setVariable("angstrom", 1.e-10 * m); + + // --- honors Enrico Fermi (1901-1954) of Italy + setVariable("fermi", 1.e-15 * m); + + // Length^2 + + setVariable("m2", m*m); + setVariable("mm2", mm*mm); + setVariable("cm2", cm*cm); + setVariable("km2", km*km); + + const double barn = 1.e-28 * m*m; + setVariable("barn", barn); + setVariable("millibarn", milli_ * barn); + setVariable("mbarn", milli_ * barn); + setVariable("microbarn", micro_ * barn); + setVariable("nanobarn", nano_ * barn); + setVariable("picobarn", pico_ * barn); + + // LengthL^3 + + setVariable("m3", m*m*m); + setVariable("mm3", mm*mm*mm); + setVariable("cm3", cm*cm*cm); + setVariable("cc", cm*cm*cm); + setVariable("km3", km*km*km); + + const double L = 1.e-3*m*m*m; + setVariable("liter", L); + setVariable("litre", L); + setVariable("L", L); + setVariable("centiliter", centi_ * L); + setVariable("cL", centi_ * L); + setVariable("milliliter", milli_ * L); + setVariable("mL", milli_ * L); + + // Length^-1 + + const double dpt = 1./m; + setVariable("diopter", dpt); + setVariable("dioptre", dpt); + setVariable("dpt", dpt); + + // Mass + + const double g = 0.001*kg; + setVariable("gram", g); + setVariable("g", g); + setVariable("milligram", milli_ * g); + setVariable("mg", milli_ * g); + + // Time + + setVariable("millisecond", milli_ * s); + setVariable("ms", milli_ * s); + setVariable("microsecond", micro_ * s); + setVariable("us", micro_ * s); + setVariable("nanosecond", nano_ * s); + setVariable("ns", nano_ * s); + setVariable("picosecond", pico_ * s); + setVariable("ps", pico_ * s); + + // Current + + setVariable("milliampere", milli_ * A); + setVariable("mA", milli_ * A); + setVariable("microampere", micro_ * A); + setVariable("nanoampere", nano_ * A); + + // Frequency + + setVariable("kilohertz", kilo_ * Hz); + setVariable("kHz", kilo_ * Hz); + setVariable("megahertz", mega_ * Hz); + setVariable("MHz", mega_ * Hz); + + // Force + setVariable("kilonewton", kilo_ * N); + setVariable("kN", kilo_ * N); + + // Pressure + setVariable("kilobar", kilo_ * bar); + setVariable("kbar", kilo_ * bar); + setVariable("millibar", milli_ * bar); + setVariable("mbar", milli_ * bar); + + // Energy + setVariable("kilojoule", kilo_ * J); + setVariable("kJ", kilo_ * J); + setVariable("megajoule", mega_ * J); + setVariable("MJ", mega_ * J); + setVariable("gigajoule", giga_ * J); + setVariable("GJ", giga_ * J); + + const double e_SI = 1.60217733e-19; // positron charge in coulomb + const double ePlus = e_SI * C; // positron charge + const double eV = ePlus * V; + setVariable("electronvolt", eV); + setVariable("eV", eV); + setVariable("kiloelectronvolt", kilo_ * eV); + setVariable("keV", kilo_ * eV); + setVariable("megaelectronvolt", mega_ * eV); + setVariable("MeV", mega_ * eV); + setVariable("gigaelectronvolt", giga_ * eV); + setVariable("GeV", giga_ * eV); + setVariable("teraelectronvolt", tera_ * eV); + setVariable("TeV", tera_ * eV); + setVariable("petaelectronvolt", peta_ * eV); + setVariable("PeV", peta_ * eV); + + // Power + setVariable("kilowatt", kilo_ * W); + setVariable("kW", kilo_ * W); + setVariable("megawatt", mega_ * W); + setVariable("MW", mega_ * W); + setVariable("gigawatt", giga_ * W); + setVariable("GW", giga_ * W); + + // Electric potential + setVariable("kilovolt", kilo_ * V); + setVariable("kV", kilo_ * V); + setVariable("megavolt", mega_ * V); + setVariable("MV", mega_ * V); + + // Electric capacitance + setVariable("millifarad", milli_ * F); + setVariable("mF", milli_ * F); + setVariable("microfarad", micro_ * F); + setVariable("uF", micro_ * F); + setVariable("nanofarad", nano_ * F); + setVariable("nF", nano_ * F); + setVariable("picofarad", pico_ * F); + setVariable("pF", pico_ * F); + + // Magnetic flux density + setVariable("kilogauss", kilo_ * Gs); + setVariable("kGs", kilo_ * Gs); +} + +// } // namespace HepTool diff --git a/ExpressionEvaluator/src/stack.src b/ExpressionEvaluator/src/stack.src new file mode 100755 index 0000000000000000000000000000000000000000..d8ff698ae1f78c68a030e9f0baacf9fd424c3e47 --- /dev/null +++ b/ExpressionEvaluator/src/stack.src @@ -0,0 +1,45 @@ +// -*- C++ -*- +// $Id: stack.src,v 1.1.1.1 2003/07/15 20:15:05 garren Exp $ +// --------------------------------------------------------------------------- + +#ifndef HEP_STACK_SRC +#define HEP_STACK_SRC + +/* + * Simplified stack class. + * It is intended to be used as a replacement of the standard class where + * full functionality of <stack> is not required, but it is essential + * to have highly portable and effective code. + * + * This file should be used exclusively inside *.cc files. + * Usage inside header files can result to a clash with standard <stack>. + * + * @author Evgeni Chernyaev <Evgueni.Tcherniaev@cern.ch> + */ +template<class T> +class stack { + private: + int k, max_size; + T * v; + + public: + stack() : k(0), max_size(20), v(new T[20]) {} + ~stack() { delete [] v; } + + int size() const { return k; } + T top () const { return v[k-1]; } + T & top () { return v[k-1]; } + void pop () { k--; } + void push(T a) { + if (k == max_size) { + T * w = v; + max_size *= 2; + v = new T[max_size]; + for (int i=0; i<k; i++) v[i] = w[i]; + delete [] w; + } + v[k++] = a; + } +}; + +#endif /* HEP_STACK_SRC */ diff --git a/ExpressionEvaluator/src/string.src b/ExpressionEvaluator/src/string.src new file mode 100755 index 0000000000000000000000000000000000000000..934529faa7deb663c7378adf395da6f825fb2360 --- /dev/null +++ b/ExpressionEvaluator/src/string.src @@ -0,0 +1,125 @@ +// -*- C++ -*- +// $Id: string.src,v 1.1.1.1 2003/07/15 20:15:05 garren Exp $ +// --------------------------------------------------------------------------- + +#ifndef HEP_STRING_SRC +#define HEP_STRING_SRC + +#include <iostream> +#include <string.h> + +/* + * Simplified string class. + * It provides only few basic functions of the standard <string> and + * is intended to be used as a replacement of the standard class where + * full functionality of <string> is not required, but it is essential + * to have highly portable and effective code. + * + * This file should be used exclusively inside *.cc files. + * Usage inside header files can result to a clash with standard <string>. + */ +struct string { + struct srep { + char* s; // pointer to data + int n; // reference count + srep() : n(1) {} + } *p; + + // Default constructor. + string() { p = new srep; p->s = 0; } + + // Constructor from character string. + string(const char* s) { + p = new srep; p->s = new char[strlen(s)+1]; strcpy(p->s, s); + } + + // Constructor from character substring. + string(const char* s, unsigned int n) { + p = new srep; p->s = new char[n+1]; strncpy(p->s, s, n); *(p->s+n) = '\0'; + } + + // Copy constructor from string. + string(const string& x) { x.p->n++; p = x.p; } + + // Destructor. + ~string() { if (--p->n == 0) { delete [] p->s; delete p; } } + + // Assignment from character string. + string& operator=(const char* s) { + if (p->n > 1) { // disconnect self + p->n--; + p = new srep; + }else{ + delete [] p->s; // free old string + } + p->s = new char[strlen(s)+1]; + strcpy(p->s, s); + return *this; + } + + // Assignment from string. + string& operator=(const string & x) { + x.p->n++; // protect against "st = st" + if (--p->n == 0) { delete [] p->s; delete p; } + p = x.p; + return *this; + } + + // Returns C-style character string. + const char* c_str() const { return p->s; } +}; + +// +// Concatinations. +// +inline string operator+(char a, const string & b) { + string s; s.p->s = new char[strlen(b.c_str())+2]; + s.p->s[0] = a; strcpy(s.p->s+1, b.c_str()); + return s; +} + +inline string operator+(const char * a, const string & b) { + int lena = strlen(a); + string s; s.p->s = new char[lena+strlen(b.c_str())+1]; + strcpy(s.p->s, a); strcpy(s.p->s+lena, b.c_str()); + return s; +} + +inline string operator+(const string & a, const char * b) { + int lena = strlen(a.c_str()); + string s; s.p->s = new char[lena+strlen(b)+1]; + strcpy(s.p->s, a.c_str()); strcpy(s.p->s+lena, b); + return s; +} + +inline string operator+(const string & a, const string & b) { + int lena = strlen(a.c_str()); + string s; s.p->s = new char[lena+strlen(b.c_str())+1]; + strcpy(s.p->s, a.c_str()); strcpy(s.p->s+lena, b.c_str()); + return s; +} + +// +// Comparisons. +// +inline bool operator==(const string & x, const char* s) { + return strcmp(x.p->s, s) == 0; +} +inline bool operator==(const string & x, const string & y) { + return strcmp(x.p->s, y.p->s) == 0; +} +inline bool operator!=(const string & x, const char* s) { + return strcmp(x.p->s, s) != 0; +} +inline bool operator!=(const string & x, const string & y) { + return strcmp(x.p->s, y.p->s) != 0; +} + +// +// Output to a stream. +// +std::ostream & operator<<(std::ostream & s, const string & x) { + return s << x.p->s; +} + +#endif /* HEP_STRING_SRC */ diff --git a/JSONParser/CMakeLists.txt b/JSONParser/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b01a0ee7cb8ad66530ef95f697cdf427017f444d --- /dev/null +++ b/JSONParser/CMakeLists.txt @@ -0,0 +1,46 @@ +cmake_minimum_required( VERSION 3.1 ) + +# Set up the project. +project( "JSONParser" VERSION 1.0.0 LANGUAGES CXX ) + +find_package( GeoModelCore REQUIRED ) +find_package( nlohmann_json REQUIRED ) +find_package(Eigen3 REQUIRED) + + +# Set default build options. +set( CMAKE_BUILD_TYPE "Release" CACHE STRING "CMake build mode to use" ) +set( CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard used for the build" ) +set( CMAKE_CXX_EXTENSIONS FALSE CACHE BOOL "(Dis)allow using GNU extensions" ) + +# Use the GNU install directory names. +include( GNUInstallDirs ) + +# Find the header and source files. +file( GLOB SOURCES src/*.cxx ) +file( GLOB HEADERS JSONParser/*.h ) + +# Create the library. +add_library( JSONParser SHARED ${HEADERS} ${SOURCES} ) +set_property( TARGET JSONParser + PROPERTY PUBLIC_HEADER ${HEADERS} ) +target_link_libraries( JSONParser PUBLIC nlohmann_json::nlohmann_json GeoModelCore::GeoModelKernel ) +target_include_directories( JSONParser SYSTEM PUBLIC ${EIGEN3_INCLUDE_DIR} ) +target_include_directories( JSONParser PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> ) +source_group( "JSONParser" FILES ${HEADERS} ) +source_group( "src" FILES ${SOURCES} ) + +install( TARGETS JSONParser EXPORT JSONParser-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/JSONParser ) +# +# Version the shared library. (Please update when cutting a new release!) +# +set(MYLIB_VERSION_MAJOR 1) +set(MYLIB_VERSION_MINOR 1) +set(MYLIB_VERSION_PATCH 0) +set(MYLIB_VERSION_STRING ${MYLIB_VERSION_MAJOR}.${MYLIB_VERSION_MINOR}.${MYLIB_VERSION_PATCH}) + +set_target_properties(JSONParser PROPERTIES VERSION ${MYLIB_VERSION_STRING} SOVERSION ${MYLIB_VERSION_MAJOR}) + diff --git a/JSONParser/JSONParser/JSONDocument.h b/JSONParser/JSONParser/JSONDocument.h new file mode 100644 index 0000000000000000000000000000000000000000..718b434e0e3558c29f38c22ba95f17799c81032c --- /dev/null +++ b/JSONParser/JSONParser/JSONDocument.h @@ -0,0 +1,32 @@ +#pragma once + +#include "GeoModelKernel/GeoDefinitions.h" +#include <map> +#include <vector> +#include <string> + +struct point { + std::string key; + std::string unit; + double x; + double y; + double z; +}; + +struct facet { + std::string type; + int nVertices; + std::vector<std::string> vertices; +}; + +struct tessellated { + std::string name; + std::vector<facet> facets; + std::map<std::string, point, std::less<std::string> > points; +}; + +class JSONDocument { +public: + tessellated solidRep; +// std::map<std::string, tessellated, std::less<std::string> > tessellatedSolids; +}; diff --git a/JSONParser/JSONParser/JSONHandler.h b/JSONParser/JSONParser/JSONHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..d5e4a310c208d98fa10aa53dd70a47327880152d --- /dev/null +++ b/JSONParser/JSONParser/JSONHandler.h @@ -0,0 +1,28 @@ +#ifndef JSONHandler_H +#define JSONHandler_H + +#include <map> +#include <string> + +#include "nlohmann/json.hpp" + +using nlohmann::json; + +#include "handlerStore.h" + +class JSONHandler { + +friend class handlerStore; + +public: + virtual void ElementHandle(const json& j) = 0; + std::string name() {return _name;} +protected: + JSONHandler(std::string n):_name(n) {handlerStore::getHandlerStore()->registerHandler(this);} + virtual ~JSONHandler() {;} +private: + std::string _name; + std::map<std::string, JSONHandler*,std::less<std::string> > registeredHandlers; +}; + +#endif diff --git a/JSONParser/JSONParser/JSONParser.h b/JSONParser/JSONParser/JSONParser.h new file mode 100644 index 0000000000000000000000000000000000000000..c07e3ffc5588cc4ebc5fa579af8a235eeec87abd --- /dev/null +++ b/JSONParser/JSONParser/JSONParser.h @@ -0,0 +1,55 @@ +#ifndef JSONParser_H +#define JSONParser_H + +#include <nlohmann/json.hpp> +#include <iostream> +#include <fstream> +#include <sstream> +#include <string> + +#include "JSONParser/handlerStore.h" +#include "JSONParser/JSONHandler.h" + +using json = nlohmann::json; + +class JSONParser { +public: + JSONParser() {addFile("Units.js");} + JSONParser(const char* files) + { + //addFile("Units.js"); + std::istringstream iss(files); + std::string token; + while (std::getline(iss, token, ':')) + { + std::cout <<" file added "<<token<<std::endl; + addFile(token); + } + } + void addFile(std::string n) {fileNames.push_back(n);} + void parse() + { + for (auto it: fileNames) + { + std::ifstream i(it); + json j = json::parse(i); + json &jj=j; + IterateModel(jj); + } + } + inline void IterateModel(json&); +private: + std::vector<std::string> fileNames; +}; + +void JSONParser::IterateModel(json& jj) +{ + for (auto it = jj.begin(); it != jj.end(); ++it) + { + std::string key=it.key(); + JSONHandler *h=handlerStore::getHandlerStore()->getHandler(key); + h->ElementHandle(it.value()); + } +} + +#endif diff --git a/JSONParser/JSONParser/facetsHandler.h b/JSONParser/JSONParser/facetsHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..5b782d9d3c0eed58df53745c5bfb521478203b1b --- /dev/null +++ b/JSONParser/JSONParser/facetsHandler.h @@ -0,0 +1,50 @@ +#pragma once + +#include <string> +#include "nlohmann/json.hpp" +#include "JSONParser/JSONHandler.h" +#include "JSONParser/handlerStore.h" +#include "JSONParser/JSONDocument.h" + +extern JSONDocument jDocument; + +class facetsHandler: public JSONHandler { + +friend class handlerStore; + +public: + virtual void ElementHandle(const json& j) + { + std::cout<<"--------> Handling for facets!!!"<<std::endl; + + for (auto it=j.begin(); it!=j.end() ; it++) + { + facet f; + f.nVertices=0; + + const json& jj=it.value(); + for (auto ir=jj.begin();ir!=jj.end();ir++) + { + const json& jk=ir.value(); + if (jk.is_string()) + f.type=jk; + else if (jk.is_array()) + for (auto iz=jk.begin();iz!=jk.end();iz++) + { + f.nVertices++; + f.vertices.push_back(*iz); + } + } + jDocument.solidRep.facets.push_back(f); + + } + + } + +protected: + facetsHandler(std::string n):JSONHandler(n) + { + } + +}; + diff --git a/JSONParser/JSONParser/handlerStore.h b/JSONParser/JSONParser/handlerStore.h new file mode 100644 index 0000000000000000000000000000000000000000..5f6e396b961054551b3dfba236ab647ca1a227c2 --- /dev/null +++ b/JSONParser/JSONParser/handlerStore.h @@ -0,0 +1,29 @@ +#ifndef HandlerStore_H +#define HandlerStore_H + +#include <iostream> +#include <string> +#include <map> + +class JSONHandler; + +class handlerStore { +public: + static handlerStore* getHandlerStore() ; + void registerHandler(JSONHandler* h) ; + JSONHandler* getHandler(std::string name) ; + void listHandlers(); + template <typename T> static T* createHandler(std::string n) + { + return new T(n); + } + +private: + handlerStore() + { + std::cout<<" this is the handlerStore being created"<<std::endl; + } + std::map< std::string, JSONHandler*, std::less<std::string> > store; +}; + +#endif diff --git a/JSONParser/JSONParser/pointsHandler.h b/JSONParser/JSONParser/pointsHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..15f6753fcbb39939066bbf0c1aab0093b25423ea --- /dev/null +++ b/JSONParser/JSONParser/pointsHandler.h @@ -0,0 +1,40 @@ +#pragma once + +#include <string> +#include "nlohmann/json.hpp" +#include "JSONParser/JSONHandler.h" +#include "JSONParser/handlerStore.h" +#include "JSONParser/JSONDocument.h" + +extern JSONDocument jDocument; + +class pointsHandler: public JSONHandler { + +friend class handlerStore; + +public: + virtual void ElementHandle(const json& j) + { + std::cout<<"--------> Handling for points!!! new version"<<std::endl; + + for (auto it=j.begin();it!=j.end();it++) + { + point p; + const json& jj=it.value(); + auto ir =jj.begin(); + p.key=ir.key(); + p.unit = (ir.value())["unit"]; + p.x=(ir.value())["x"]; + p.y=(ir.value())["y"]; + p.z=(ir.value())["z"]; + jDocument.solidRep.points[p.key]=p; + } + } + +protected: + pointsHandler(std::string n):JSONHandler(n) + { + } + +}; + diff --git a/JSONParser/JSONParser/tessellatedHandler.h b/JSONParser/JSONParser/tessellatedHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..9a88fc6f3e7a01a086920bf9c682d8964c9eb462 --- /dev/null +++ b/JSONParser/JSONParser/tessellatedHandler.h @@ -0,0 +1,28 @@ +#pragma once + +#include <string> +#include "JSONParser/JSONDocument.h" +#include "nlohmann/json.hpp" +#include "JSONParser/JSONHandler.h" +#include "JSONParser/handlerStore.h" + +extern JSONDocument jDocument; + +class tessellatedHandler: public JSONHandler { + +friend class handlerStore; + +public: + virtual void ElementHandle(const json& j) + { + std::cout<<"--------> Handling for tessellated!!! "<<j<<std::endl; + jDocument.solidRep.name=j["name"]; + } + +protected: + tessellatedHandler(std::string n):JSONHandler(n) + { + } + +}; + diff --git a/JSONParser/src/handlerStore.cxx b/JSONParser/src/handlerStore.cxx new file mode 100644 index 0000000000000000000000000000000000000000..227e5a09b2232277b718d08c6785acc7218363c7 --- /dev/null +++ b/JSONParser/src/handlerStore.cxx @@ -0,0 +1,32 @@ +#include "JSONParser/handlerStore.h" +#include "JSONParser/JSONHandler.h" + +handlerStore* handlerStore::getHandlerStore() +{ + static handlerStore *theStore=new handlerStore(); + return theStore; +} + +void handlerStore::registerHandler(JSONHandler* h) +{ + std::cout<<"registering JSONHandler "<<h->name()<<std::endl; + store[h->name()]=h; +} +JSONHandler* handlerStore::getHandler(std::string name) +{ + if (store.find(name)!=store.end()) return store[name]; + else + { + std::cout<<" JSONHandler "<<name<<" not found in store!!"<<std::endl; + return 0; + } + +} +void handlerStore::listHandlers() +{ + std::cout<<" HandlerStore: list of available level 0th handlers"<<std::endl; + for (auto it: store) + { + std::cout<<"\t\t---> Handler "<<(it.second)->name()<<std::endl; + } +} diff --git a/JSONParser/src/handlers.cxx b/JSONParser/src/handlers.cxx new file mode 100644 index 0000000000000000000000000000000000000000..0937dc5c9965815ddf1faec407455b43705a092b --- /dev/null +++ b/JSONParser/src/handlers.cxx @@ -0,0 +1,8 @@ +#include "JSONParser/tessellatedHandler.h" +#include "JSONParser/pointsHandler.h" +#include "JSONParser/facetsHandler.h" + +JSONHandler* jh1=handlerStore::createHandler<tessellatedHandler>("1_tessellated"); +JSONHandler* jh2=handlerStore::createHandler<pointsHandler>("2_Points"); +JSONHandler* jh3=handlerStore::createHandler<facetsHandler>("3_Facets"); + diff --git a/JSONParser/src/serializers.cxx b/JSONParser/src/serializers.cxx new file mode 100644 index 0000000000000000000000000000000000000000..f4b95da675453cc87d595f13fa19e12b0a8d6c40 --- /dev/null +++ b/JSONParser/src/serializers.cxx @@ -0,0 +1,29 @@ + +#include "JSONParser/JSONDocument.h" +#include <nlohmann/json.hpp> +using nlohmann::json; + +JSONDocument jDocument; + +void to_json(json& j, const point& p) +{ + j={ + {p.key,{ + {"unit",p.unit},{"x",p.x},{"y",p.y},{"z",p.z} + }} + }; +} + +void from_json(const json& j, point& p) +{ + for (auto it=j.begin();it!=j.end();it++) + { + const json& jj=it.value(); + auto ir =jj.begin(); + p.key=ir.key(); + p.unit = (ir.value())["unit"]; + p.x=(ir.value())["x"]; + p.y=(ir.value())["y"]; + p.z=(ir.value())["z"]; + } +} diff --git a/README.md b/README.md index 69e59dfadeafcefc45765755bdbff1bccd812763..d687fbab66729a2c97dce1244b2c3d2800aa253c 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -# GeoModelTools +# GeoModelTools -The projects gathers tools and utilities which ease the development of GeoModel-based software \ No newline at end of file +Tools and utilities for GeoModel-based detector description projects diff --git a/XMLParser/CMakeLists.txt b/XMLParser/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..b6f28d25d12a7c6343fcc19cb423d0bcb85d76cb --- /dev/null +++ b/XMLParser/CMakeLists.txt @@ -0,0 +1,56 @@ +cmake_minimum_required( VERSION 3.1 ) + +# Set up the project. +project( "XMLParser" VERSION 1.0.0 LANGUAGES CXX ) + +find_package( GeoModelCore REQUIRED ) +find_package( XercesC REQUIRED ) + + +# Set default build options. +set( CMAKE_BUILD_TYPE "Release" CACHE STRING "CMake build mode to use" ) +set( CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard used for the build" ) +set( CMAKE_CXX_EXTENSIONS FALSE CACHE BOOL "(Dis)allow using GNU extensions" ) + +# Use the GNU install directory names. +include( GNUInstallDirs ) + +# Find the header and source files. +file( GLOB SOURCES src/*.cxx ) +file( GLOB HEADERS XMLParser/*.h ) + +# Create the library. +add_library( XMLParser SHARED ${HEADERS} ${SOURCES} ) +set_property( TARGET XMLParser + PROPERTY PUBLIC_HEADER ${HEADERS} ) +target_link_libraries( XMLParser PUBLIC ExpressionEvaluator XercesC::XercesC GeoModelCore::GeoModelKernel ) +target_include_directories( XMLParser SYSTEM PUBLIC ) +target_include_directories( XMLParser PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:include> ) +source_group( "XMLParser" FILES ${HEADERS} ) +source_group( "src" FILES ${SOURCES} ) + +# # Install the library. +# install( TARGETS XMLParser +# EXPORT XMLParser +# LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} +# PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/XMLParser ) + +# Install a CMake description of the project/library. +# install( EXPORT XMLParser DESTINATION cmake ) + + +# new test GeoModelCore +install( TARGETS XMLParser EXPORT XMLParser-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/XMLParser ) +# +# Version the shared library. (Please update when cutting a new release!) +# +set(MYLIB_VERSION_MAJOR 1) +set(MYLIB_VERSION_MINOR 1) +set(MYLIB_VERSION_PATCH 0) +set(MYLIB_VERSION_STRING ${MYLIB_VERSION_MAJOR}.${MYLIB_VERSION_MINOR}.${MYLIB_VERSION_PATCH}) + +set_target_properties(XMLParser PROPERTIES VERSION ${MYLIB_VERSION_STRING} SOVERSION ${MYLIB_VERSION_MAJOR}) + diff --git a/XMLParser/XMLParser/IAGDDParser.h b/XMLParser/XMLParser/IAGDDParser.h new file mode 100644 index 0000000000000000000000000000000000000000..8e3d257624b9b2d2402414e3954e233b99be7daf --- /dev/null +++ b/XMLParser/XMLParser/IAGDDParser.h @@ -0,0 +1,26 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef IAGDDParser_H +#define IAGDDParser_H + + +#include <string> + +class IAGDDParser { +public: + IAGDDParser():m_fileName("") {} + IAGDDParser(std::string s):m_fileName(s) {} + virtual ~IAGDDParser() {;} + virtual bool ParseFile(std::string)=0; + virtual bool ParseFileAndNavigate(std::string)=0; + virtual bool ParseString(std::string)=0; + virtual bool ParseStringAndNavigate(std::string)=0; + virtual bool WriteToFile(std::string)=0; + virtual void navigateTree()=0; +protected: + std::string m_fileName; +}; + +#endif diff --git a/XMLParser/XMLParser/XMLHandler.h b/XMLParser/XMLParser/XMLHandler.h new file mode 100644 index 0000000000000000000000000000000000000000..79fe487e84181173b04ac6247446b55ce00837ec --- /dev/null +++ b/XMLParser/XMLParser/XMLHandler.h @@ -0,0 +1,65 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef XMLHandler_H +#define XMLHandler_H + +#include <string> +#include <xercesc/dom/DOM.hpp> + +#include "ExpressionEvaluator/ExpressionEvaluator.h" + +class XMLHandlerStore; + +class XMLHandler { +public: + XMLHandler(std::string n); + virtual ~XMLHandler() {} + std::string GetName() {return m_name;} + virtual void ElementHandle()=0; + virtual void Handle(xercesc::DOMNode *t) + { + SetCurrentElement(t); + ElementHandle(); + } + void StopLoop(bool); + bool IsLoopToBeStopped(); +protected: + std::string m_name; + bool m_stopLoop; + + static xercesc::DOMNode *s_currentElement; + static void SetCurrentElement(xercesc::DOMNode *t) {s_currentElement=t;} + static xercesc::DOMNode *GetCurrentElement() {return s_currentElement;} + + bool isAttribute(const std::string) const; + + std::string getAttribute(const std::string, bool&) const; + std::string getAttributeAsString(const std::string) const; + double getAttributeAsDouble(const std::string) const; + int getAttributeAsInt(const std::string) const; + std::vector<double> getAttributeAsVector(const std::string) const; + std::vector<int> getAttributeAsIntVector(const std::string) const; + std::string getAttributeAsString(const std::string, bool&) const; + double getAttributeAsDouble(const std::string, bool&) const; + int getAttributeAsInt(const std::string, bool&) const; + std::vector<double> getAttributeAsVector(const std::string, bool&) const; + std::vector<int> getAttributeAsIntVector(const std::string, bool&) const; + std::string getAttributeAsString(const std::string, const std::string) const; + double getAttributeAsDouble(const std::string, const double) const; + int getAttributeAsInt(const std::string, const int) const; + std::vector<double> getAttributeAsVector(const std::string, const std::vector<double>) const; + std::vector<int> getAttributeAsIntVector(const std::string, const std::vector<int>) const; + static bool s_printFlag; + + ExpressionEvaluator* Evaluator() const + { + static ExpressionEvaluator* eval=ExpressionEvaluator::GetEvaluator(); + return eval; + } +private: + void RegisterToStore(); +}; + +#endif diff --git a/XMLParser/XMLParser/XMLHandlerStore.h b/XMLParser/XMLParser/XMLHandlerStore.h new file mode 100644 index 0000000000000000000000000000000000000000..429ab294860c87e6e3d52f0f483e137ffe7fe9a4 --- /dev/null +++ b/XMLParser/XMLParser/XMLHandlerStore.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef XMLHandlerStore_H +#define XMLHandlerStore_H + +class XMLHandler; + +#include <map> +#include <string> + +#include <xercesc/dom/DOM.hpp> + +//using namespace xercesc; + +typedef std::map<std::string,XMLHandler*,std::less<std::string> > handlerStore; + +class XMLHandlerStore:public handlerStore { +public: + static XMLHandlerStore* GetHandlerStore(); + void RegisterHandler(XMLHandler*); + XMLHandler* GetHandler(xercesc::DOMNode *); + void Handle(xercesc::DOMNode *); +private: + XMLHandlerStore(); + static XMLHandlerStore *s_theStore; +}; + +#endif diff --git a/XMLParser/XMLParser/XercesParser.h b/XMLParser/XMLParser/XercesParser.h new file mode 100644 index 0000000000000000000000000000000000000000..d8c8ee3207ada431f8d468989ad65e69be9fb837 --- /dev/null +++ b/XMLParser/XMLParser/XercesParser.h @@ -0,0 +1,42 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#ifndef XercesParser_H +#define XercesParser_H + +#include <string> +#include "XMLParser/IAGDDParser.h" + +#include <xercesc/dom/DOM.hpp> +#include <xercesc/parsers/XercesDOMParser.hpp> + +//using namespace xercesc; + +class XercesParser: public IAGDDParser { +public: + XercesParser(); + XercesParser(std::string); + ~XercesParser(); + bool ParseFile(std::string); + bool ParseFileAndNavigate(std::string); + bool ParseString(std::string); + bool ParseStringAndNavigate(std::string); + bool WriteToFile(std::string); + void navigateTree(); + static void elementLoop(); + static void elementLoop(xercesc::DOMNode*); + static xercesc::DOMNode* GetCurrentElement() {return s_currentElement;} + bool Initialize(); + bool Finalize(); +private: + xercesc::DOMDocument *m_doc; + + xercesc::XercesDOMParser *m_parser; + + bool m_initialized; +protected: + static xercesc::DOMNode *s_currentElement; +}; + +#endif diff --git a/XMLParser/src/XMLHandler.cxx b/XMLParser/src/XMLHandler.cxx new file mode 100644 index 0000000000000000000000000000000000000000..46b86c3e68bdc456f33214791fb850c829222e69 --- /dev/null +++ b/XMLParser/src/XMLHandler.cxx @@ -0,0 +1,237 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "XMLParser/XMLHandler.h" +#include "XMLParser/XMLHandlerStore.h" + +#include "ExpressionEvaluator/ExpressionEvaluator.h" + +#include <vector> + +using namespace xercesc; + +DOMNode* XMLHandler::s_currentElement=0; +bool XMLHandler::s_printFlag=false; + +XMLHandler::XMLHandler(std::string n):m_name(n) +{ +// std::cout<< " creating new handler "<<n<<std::endl; + m_stopLoop=false; + RegisterToStore(); +} + +void XMLHandler::RegisterToStore() +{ + XMLHandlerStore::GetHandlerStore()->RegisterHandler(this); +} + +void XMLHandler::StopLoop(bool v) +{ + m_stopLoop=v; +} +bool XMLHandler::IsLoopToBeStopped() +{ + return m_stopLoop; +} +bool XMLHandler::isAttribute(const std::string name) const +{ + bool res; + std::string temp=getAttribute(name,res); + return res; +} +std::string XMLHandler::getAttribute(const std::string name, bool& isPresent) const +{ + std::string retValue=""; + isPresent=false; + if (s_currentElement->hasAttributes()) { + DOMNamedNodeMap *pAttributes = s_currentElement->getAttributes(); + DOMAttr *pAttributeNode = (DOMAttr*) pAttributes->getNamedItem(XMLString::transcode(name.c_str())); + if (pAttributeNode) { + + char* val=XMLString::transcode(pAttributeNode->getValue()); + if (val) { + + isPresent=true; + retValue=val; + XMLString::release(&val); + return retValue; + } + } + else return retValue; + + } + return retValue; +} +std::string XMLHandler::getAttributeAsString(const std::string name) const +{ + bool isPresent; + std::string temp=getAttribute(name,isPresent); + if (!isPresent) throw; + return temp; +} +double XMLHandler::getAttributeAsDouble(const std::string name) const +{ + double res=0.; + bool isPresent; + std::string temp=getAttribute(name,isPresent); + if (!isPresent) throw; + res=ExpressionEvaluator::GetEvaluator()->Eval(temp.c_str()); + return res; +} +int XMLHandler::getAttributeAsInt(const std::string name) const +{ + int res=0; + bool isPresent; + std::string temp=getAttribute(name,isPresent); + if (!isPresent) throw; + res=ExpressionEvaluator::GetEvaluator()->Eval(temp.c_str()); + return res; +} +std::vector<double> XMLHandler::getAttributeAsVector(const std::string name) const +{ + bool isPresent; + std::vector<double> vect; + std::string temp=getAttribute(name,isPresent); + if (!isPresent) throw; + std::vector<std::string> v=ExpressionEvaluator::GetEvaluator()->tokenize(";",temp); + for (unsigned int i=0;i<v.size();i++) + { + vect.push_back(ExpressionEvaluator::GetEvaluator()->Eval(v[i].c_str())); + } + return vect; +} + +std::vector<int> XMLHandler::getAttributeAsIntVector(const std::string name) const +{ + bool isPresent; + std::vector<int> vect; + std::string temp=getAttribute(name,isPresent); + if (!isPresent) throw; + std::vector<std::string> v=ExpressionEvaluator::GetEvaluator()->tokenize(";",temp); + for (unsigned int i=0;i<v.size();i++) + { + vect.push_back(ExpressionEvaluator::GetEvaluator()->Eval(v[i].c_str())); + } + return vect; +} + +std::string XMLHandler::getAttributeAsString(const std::string name, bool& isPresent) const +{ + std::string temp=getAttribute(name,isPresent); + return temp; +} +double XMLHandler::getAttributeAsDouble(const std::string name, bool& isPresent) const +{ + double res=0.; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + res=ExpressionEvaluator::GetEvaluator()->Eval(temp.c_str()); + } + return res; +} +int XMLHandler::getAttributeAsInt(const std::string name, bool& isPresent) const +{ + int res=0; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + res=ExpressionEvaluator::GetEvaluator()->Eval(temp.c_str()); + } + return res; +} +std::vector<double> XMLHandler::getAttributeAsVector(const std::string name, bool& isPresent) const +{ + std::vector<double> vect; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + std::vector<std::string> v=ExpressionEvaluator::GetEvaluator()->tokenize(";",temp); + for (unsigned int i=0;i<v.size();i++) + { + vect.push_back(ExpressionEvaluator::GetEvaluator()->Eval(v[i].c_str())); + } + } + return vect; +} + +std::vector<int> XMLHandler::getAttributeAsIntVector(const std::string name, bool& isPresent) const +{ + std::vector<int> vect; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + std::vector<std::string> v=ExpressionEvaluator::GetEvaluator()->tokenize(";",temp); + for (unsigned int i=0;i<v.size();i++) + { + vect.push_back(ExpressionEvaluator::GetEvaluator()->Eval(v[i].c_str())); + } + } + return vect; +} + +std::string XMLHandler::getAttributeAsString(const std::string name, const std::string def) const +{ + bool isPresent; + std::string temp=getAttribute(name,isPresent); + if (isPresent) return temp; + else return def; +} +double XMLHandler::getAttributeAsDouble(const std::string name, const double def) const +{ + bool isPresent; + double res=0.; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + res=ExpressionEvaluator::GetEvaluator()->Eval(temp.c_str()); + return res; + } + return def; +} +int XMLHandler::getAttributeAsInt(const std::string name, const int def) const +{ + bool isPresent; + int res=0; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + res=ExpressionEvaluator::GetEvaluator()->Eval(temp.c_str()); + return res; + } + return def; +} +std::vector<double> XMLHandler::getAttributeAsVector(const std::string name, const std::vector<double> def) const +{ + bool isPresent; + std::vector<double> vect; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + std::vector<std::string> v=ExpressionEvaluator::GetEvaluator()->tokenize(";",temp); + for (unsigned int i=0;i<v.size();i++) + { + vect.push_back(ExpressionEvaluator::GetEvaluator()->Eval(v[i].c_str())); + } + return vect; + } + return def; +} + +std::vector<int> XMLHandler::getAttributeAsIntVector(const std::string name, const std::vector<int> def) const +{ + bool isPresent; + std::vector<int> vect; + std::string temp=getAttribute(name,isPresent); + if (isPresent) + { + std::vector<std::string> v=ExpressionEvaluator::GetEvaluator()->tokenize(";",temp); + for (unsigned int i=0;i<v.size();i++) + { + vect.push_back(ExpressionEvaluator::GetEvaluator()->Eval(v[i].c_str())); + } + return vect; + } + return def; +} diff --git a/XMLParser/src/XMLHandlerStore.cxx b/XMLParser/src/XMLHandlerStore.cxx new file mode 100644 index 0000000000000000000000000000000000000000..fc56a04b2662ff6c491eab3aa9fa55bb0017ccae --- /dev/null +++ b/XMLParser/src/XMLHandlerStore.cxx @@ -0,0 +1,57 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include "XMLParser/XMLHandlerStore.h" +#include "XMLParser/XMLHandler.h" + +#include <iostream> + +using namespace xercesc; + +XMLHandlerStore* XMLHandlerStore::s_theStore=0; + +XMLHandlerStore::XMLHandlerStore() +{ +} + +XMLHandlerStore* XMLHandlerStore::GetHandlerStore() +{ + if (!s_theStore) s_theStore=new XMLHandlerStore; + return s_theStore; +} + +void XMLHandlerStore::RegisterHandler(XMLHandler* handler) +{ + std::string name=handler->GetName(); + if (this->find(name)!=this->end()) + std::cout<<" handler "<<name<<" already defined!"<<std::endl; + else + (*this)[name]=handler; +} + +void XMLHandlerStore::Handle(DOMNode *element) +{ + char* temp=XMLString::transcode(element->getNodeName()); + std::string name=temp; + XMLString::release(&temp); + if (this->find(name)!=this->end()) + ((*this)[name])->Handle(element); + else + std::cout<<" Handler for "<<name<<" not found! continuing"<<std::endl; +} + +XMLHandler* XMLHandlerStore::GetHandler(DOMNode *element) +{ + char* temp=XMLString::transcode(element->getNodeName()); + std::string name=temp; + XMLString::release(&temp); + if (this->find(name)!=this->end()) + return (*this)[name]; + else + { + std::cout<<" Handler for "<<name<<" not found! continuing"<<std::endl; + return 0; + } +} + diff --git a/XMLParser/src/XercesParser.cxx b/XMLParser/src/XercesParser.cxx new file mode 100644 index 0000000000000000000000000000000000000000..89ae10f44051123396fd9153e166e7eb3a249686 --- /dev/null +++ b/XMLParser/src/XercesParser.cxx @@ -0,0 +1,281 @@ +/* + Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration +*/ + +#include <iostream> + +#include "XMLParser/XercesParser.h" +#include "XMLParser/XMLHandler.h" +#include "XMLParser/XMLHandlerStore.h" + +#include "xercesc/util/PlatformUtils.hpp" +#include "xercesc/util/XMLException.hpp" + +#include <xercesc/dom/DOM.hpp> + +#include <xercesc/framework/StdOutFormatTarget.hpp> +#include <xercesc/framework/LocalFileFormatTarget.hpp> +#include <xercesc/framework/MemBufInputSource.hpp> +#include <xercesc/parsers/XercesDOMParser.hpp> +#include <xercesc/util/XMLUni.hpp> + +#include <xercesc/util/OutOfMemoryException.hpp> + +using namespace xercesc; + +DOMNode* XercesParser::s_currentElement=0; + +XercesParser::~XercesParser() +{ + delete m_parser; + m_parser=0; + Finalize(); +} + +XercesParser::XercesParser():IAGDDParser(),m_doc(0),m_parser(0),m_initialized(false) +{ +// std::cout<<"+++++++++++> Xerces Parser being created!" <<std::endl; +// AGDDController::GetController()->SetParser(this); +// std::cout<<"exiting constructor"<<std::endl; +} +XercesParser::XercesParser(std::string s):IAGDDParser(s),m_doc(0),m_parser(0),m_initialized(false) +{ +// std::cout<<"+++++++++++> Xerces Parser being created!" <<std::endl; +// AGDDController::GetController()->SetParser(this); +// std::cout<<"exiting constructor"<<std::endl; +} +bool XercesParser::ParseFile(std::string s) +{ +// std::cout<<"+++++++++++> Xerces Parser parsing file "<<s <<std::endl; + m_fileName=s; + //s=PathResolver::find_file(s,"XMLPATH",PathResolver::RecursiveSearch); + if (s.empty()) + std::cout<<" something wrong, could not find XML file "<<s<<std::endl; + else + { +// std::cout<<" loading file "<<s<<std::endl; + if (!m_initialized) Initialize(); + m_parser = new XercesDOMParser; + bool errorsOccured = false; + try + { + m_parser->parse(s.c_str()); + } + catch (const OutOfMemoryException&) + { + XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl; + errorsOccured = true; + } + catch (const XMLException& e) + { + XERCES_STD_QUALIFIER cerr << "An error occurred during parsing\n Message: " + << XMLString::transcode(e.getMessage()) << XERCES_STD_QUALIFIER endl; + errorsOccured = true; + } + catch (const DOMException& e) + { + const unsigned int maxChars = 2047; + XMLCh errText[maxChars + 1]; + + XERCES_STD_QUALIFIER cerr << "\nDOM Error during parsing: '" << s << "'\n" + << "DOMException code is: " << e.code << XERCES_STD_QUALIFIER endl; + + if (DOMImplementation::loadDOMExceptionMsg(e.code, errText, maxChars)) + XERCES_STD_QUALIFIER cerr << "Message is: " << XMLString::transcode(errText) << XERCES_STD_QUALIFIER endl; + + errorsOccured = true; + } + + catch (...) + { + XERCES_STD_QUALIFIER cerr << "An error occurred during parsing\n " << XERCES_STD_QUALIFIER endl; + errorsOccured = true; + } + m_doc=m_parser->getDocument(); + return errorsOccured; + } + + return false; + +} +bool XercesParser::ParseFileAndNavigate(std::string s) +{ +// std::cout<<"+++++++++++> Xerces Parser parsing and navigating file "<<s <<std::endl; + bool errorOccured = ParseFile(s); + if (!errorOccured) navigateTree(); + return true; +} +bool XercesParser::ParseString(std::string s) +{ +// std::cout<<"+++++++++++> Xerces Parser parsing string "<<std::endl; +// std::cout<<s<<std::endl; + const char* str=s.c_str(); + static const char* memBufID="prodInfo"; + MemBufInputSource* memBuf = new MemBufInputSource((const XMLByte*)str,strlen(str),memBufID,false); + m_parser = new XercesDOMParser; + bool errorsOccured = false; + if (!m_initialized) Initialize(); + try + { + m_parser->parse(*memBuf); + } + catch (const OutOfMemoryException&) + { + XERCES_STD_QUALIFIER cerr << "OutOfMemoryException" << XERCES_STD_QUALIFIER endl; + errorsOccured = true; + } + catch (const XMLException& e) + { + XERCES_STD_QUALIFIER cerr << "An error occurred during parsing\n Message: " + << XMLString::transcode(e.getMessage()) << XERCES_STD_QUALIFIER endl; + errorsOccured = true; + } + catch (const DOMException& e) + { + const unsigned int maxChars = 2047; + XMLCh errText[maxChars + 1]; + + XERCES_STD_QUALIFIER cerr << "\nDOM Error during parsing: '" << s << "'\n" + << "DOMException code is: " << e.code << XERCES_STD_QUALIFIER endl; + + if (DOMImplementation::loadDOMExceptionMsg(e.code, errText, maxChars)) + XERCES_STD_QUALIFIER cerr << "Message is: " << XMLString::transcode(errText) << XERCES_STD_QUALIFIER endl; + + errorsOccured = true; + } + + catch (...) + { + XERCES_STD_QUALIFIER cerr << "An error occurred during parsing\n " << XERCES_STD_QUALIFIER endl; + errorsOccured = true; + } + m_doc=m_parser->getDocument(); + return errorsOccured; +} +bool XercesParser::ParseStringAndNavigate(std::string s) +{ +// std::cout<<"+++++++++++> Xerces Parser parsing and navigating string "<<s <<std::endl; + + bool errorOccured = ParseString(s); + if (!errorOccured) navigateTree(); + return true; +} + +bool XercesParser::WriteToFile(std::string s) +{ + XMLCh tempStr[100]; + XMLString::transcode("LS 3.0 Core 2.0", tempStr, 99); + DOMImplementation* implementation = DOMImplementationRegistry::getDOMImplementation(tempStr); + DOMLSSerializer* serializer = ((DOMImplementationLS*)implementation)->createLSSerializer(); + // if one wants a nicely indented file -- not in this case as it goes to the DB and be compressed + // DOMConfiguration* domconfig = serializer->getDomConfig(); + // domconfig->setParameter(XMLUni::fgDOMWRTFormatPrettyPrint, true); + XMLFormatTarget* target = new LocalFileFormatTarget(s.c_str()); + DOMLSOutput* domoutput = ((DOMImplementationLS*)implementation)->createLSOutput(); + // remove all comments + if( m_doc->getDOMConfig()->canSetParameter(XMLUni::fgDOMComments, true) ) m_doc->getDOMConfig()->setParameter(XMLUni::fgDOMComments, false); + m_doc->normalizeDocument(); + + domoutput->setByteStream(target); + serializer->write(m_doc, domoutput); + domoutput->release(); + serializer->release(); + delete target; + + return true; +} + +void XercesParser::navigateTree() +{ + if (!m_doc) + { + std::cout<<" something is wrong! no document set!"<<std::endl; + std::cout<<" doing nothing!"<<std::endl; + return; + } + DOMNode* node = 0; + node = dynamic_cast<DOMNode*>(m_doc->getDocumentElement()); + if( !node ) throw; + s_currentElement=node; + elementLoop(node); +} + +void XercesParser::elementLoop() +{ +} + +void XercesParser::elementLoop(DOMNode *e) +{ + if (!e) + { + std::cout<<"Calling elementLoop() with NULL pointer!!!"<<std::endl; + return; + } + if (!(e->getNodeType()==DOMNode::ELEMENT_NODE)) return; + s_currentElement=e; + XMLHandler *h=XMLHandlerStore::GetHandlerStore()->GetHandler(e); + bool stopLoop=false; + if (h) + { + h->Handle(e); + stopLoop=h->IsLoopToBeStopped(); + } + DOMNode *child; + std::string sName; + if (!stopLoop && e) + { + char* name=XMLString::transcode(e->getNodeName()); + sName=name; +// std::cout <<" found element "<<name<<std::endl; + XMLString::release(&name); + for (child=e->getFirstChild();child!=0;child=child->getNextSibling()) + { + if (child->getNodeType()==DOMNode::ELEMENT_NODE) { +// std::cout<<sName<<" child name "<<XMLString::transcode(child->getNodeName())<<std::endl; + elementLoop(child); + } + } + } +// XMLHandler *h=XMLHandlerStore::GetHandlerStore()->GetHandler(element); +// bool stopLoop=false; +// if (h) +// { +// h->Handle(element); +// stopLoop=h->IsLoopToBeStopped(); +// } +// TiXmlElement* subelement; +// subelement=element->FirstChildElement(); +// +// if (!stopLoop && subelement) +// do +// { +// // std::cout<<" \telement "<<subelement->Value()<<std::endl; +// elementLoop(subelement); +// subelement = subelement->NextSiblingElement(); +// } while (subelement); +} + +bool XercesParser::Initialize() +{ + try + { + XMLPlatformUtils::Initialize(); + } + + catch(const XMLException &toCatch) + { + XERCES_STD_QUALIFIER cerr << "Error during Xerces-c Initialization.\n" + << " Exception message:" + << XERCES_STD_QUALIFIER endl; + return 1; + } + m_initialized=true; + return 0; +} + +bool XercesParser::Finalize() +{ + XMLPlatformUtils::Terminate(); + m_initialized=false; + return 0; +} diff --git a/cmake/GeoModelToolsConfig.cmake b/cmake/GeoModelToolsConfig.cmake new file mode 100644 index 0000000000000000000000000000000000000000..4d9f1214d10766a2a55c1f58476d173b79e092d3 --- /dev/null +++ b/cmake/GeoModelToolsConfig.cmake @@ -0,0 +1,5 @@ +get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) +include(${SELF_DIR}/GeoModelTools-ExpressionEvaluator.cmake) +include(${SELF_DIR}/GeoModelTools-JSONParser.cmake) +include(${SELF_DIR}/GeoModelTools-XMLParser.cmake) +