diff --git a/.gitignore b/.gitignore index 6fc082b..dad6e6c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ *.so *.kdev4 .kdev4/* +actions-add/* \ No newline at end of file diff --git a/include/actiongenintfile.h b/actions/actiongenintfile.h similarity index 92% rename from include/actiongenintfile.h rename to actions/actiongenintfile.h index 53d7a8e..f76b9b2 100644 --- a/include/actiongenintfile.h +++ b/actions/actiongenintfile.h @@ -1,22 +1,13 @@ #pragma once #include "BFileW.h" -#include "ParseArgs.h" -#include "traits.h" +#include "actiondep.h" #include using michlib::BFileW; using michlib::Cos; using michlib::M_PI; -class ActionGenIntFile -{ - public: - static constexpr const char* name = "genintfile"; - - template static constexpr bool IsSupported = ReadIsGrid; - - template static MString DoAction(const CLArgs& args, D& data); -}; +ADD_ACTION(GenIntFile, genintfile, ReadIsGrid); template MString ActionGenIntFile::DoAction(const CLArgs& args, D& ds) { diff --git a/actions/actioninfo.h b/actions/actioninfo.h new file mode 100644 index 0000000..729f4f4 --- /dev/null +++ b/actions/actioninfo.h @@ -0,0 +1,15 @@ +#pragma once +#include "actiondep.h" +#include "merrors.h" + +using michlib::message; + +ADD_ACTION(Info, info, InfoSupported); + +template MString ActionInfo::DoAction([[maybe_unused]] const CLArgs& args, D& data) +{ + auto info = data.Info(); + if(!info.Exist()) return "No info"; + message(info); + return ""; +}; diff --git a/include/actiontsc.h b/actions/actiontsc.h similarity index 81% rename from include/actiontsc.h rename to actions/actiontsc.h index 943730c..295e504 100644 --- a/include/actiontsc.h +++ b/actions/actiontsc.h @@ -1,19 +1,11 @@ #pragma once -#include "ParseArgs.h" -#include "traits.h" +#include "actiondep.h" #include "BFileW.h" +#include using michlib::BFileW; -class ActionTSC -{ - public: - static constexpr const char* name = "tsc"; - - template static constexpr bool IsSupported = ReadPSupported || ReadSupported; - - template static MString DoAction(const CLArgs& args, D& data); -}; +ADD_ACTION(TSC, tsc, ReadPSupported || ReadSupported); template MString ActionTSC::DoAction(const CLArgs& args, D& ds) { diff --git a/include/actionuv.h b/actions/actionuv.h similarity index 92% rename from include/actionuv.h rename to actions/actionuv.h index ceb0779..dfda539 100644 --- a/include/actionuv.h +++ b/actions/actionuv.h @@ -1,16 +1,11 @@ #pragma once -#include "ParseArgs.h" -#include "traits.h" +#include "actiondep.h" +#include "BFileW.h" +#include -class ActionUV -{ - public: - static constexpr const char* name = "uv"; - - template static constexpr bool IsSupported = ReadPSupported || ReadSupported; +using michlib::BFileW; - template static MString DoAction(const CLArgs& args, D& data); -}; +ADD_ACTION(UV, uv, ReadPSupported || ReadSupported); template MString ActionUV::DoAction(const CLArgs& args, D& ds) { diff --git a/include/actiondep.h b/include/actiondep.h new file mode 100644 index 0000000..7caf65b --- /dev/null +++ b/include/actiondep.h @@ -0,0 +1,16 @@ +#pragma once +#include "ParseArgs.h" +#include "traits.h" + +#if defined GENACTIONLIST +#define ADD_ACTION(actclass, actname, suptest) ADD ACTION CLASS: actclass +#else +#define ADD_ACTION(actclass, actname, suptest) \ + class Action##actclass \ + { \ + public: \ + static constexpr const char* name = #actname; \ + template static constexpr bool IsSupported = (suptest); \ + template static MString DoAction(const CLArgs& args, Source& data); \ + }; +#endif diff --git a/include/actioninfo.h b/include/actioninfo.h deleted file mode 100644 index 43855b5..0000000 --- a/include/actioninfo.h +++ /dev/null @@ -1,24 +0,0 @@ -#pragma once -#include "ParseArgs.h" -#include "merrors.h" -#include "traits.h" - -using michlib::message; - -class ActionInfo -{ - public: - static constexpr const char* name = "info"; - - template static constexpr bool IsSupported = InfoSupported; - - template static MString DoAction(const CLArgs& args, D& data); -}; - -template MString ActionInfo::DoAction([[maybe_unused]] const CLArgs& args, D& data) -{ - auto info = data.Info(); - if(!info.Exist()) return "No info"; - message(info); - return ""; -}; diff --git a/include/actions.h b/include/actions.h index c54510f..be59a80 100644 --- a/include/actions.h +++ b/include/actions.h @@ -1,8 +1,5 @@ #pragma once -#include "actiongenintfile.h" -#include "actioninfo.h" -#include "actiontsc.h" -#include "actionuv.h" +#include "actionlist.h" #include "basedata.h" #include "mdatetime.h" #include "mregex.h" @@ -11,7 +8,7 @@ using michlib::MDateTime; -using ActionVariants = std::variant; +using ActionVariants = std::variant; class Action: public ActionVariants { diff --git a/scripts/genactionslist b/scripts/genactionslist new file mode 100755 index 0000000..74cef87 --- /dev/null +++ b/scripts/genactionslist @@ -0,0 +1,53 @@ +#!/bin/bash + +DIR="$(dirname $0)/../include" +COMPILER="$1" +OUT="$2" +shift +shift +declare -a EXCLUDE_ACTIONS=( $@ ) + +included() +{ + local name="$1" + + local i=0 + while [ $i -lt ${#EXCLUDE_ACTIONS[@]} ]; do + if [ "$name" == "${EXCLUDE_ACTIONS[$i]}" ]; then + return 1 + fi + let i++ + done + return 0 +} + +if [ -z "$COMPILER" ]; then + exit 1 +fi + +actlist="" +echo "">"$OUT" + +cdir="$(pwd)" +pushd "$DIR">/dev/null +for f in ../actions/action*.h ../actions-add/action*.h; do + if [ -f "$f" ]; then +# echo Compiler=$COMPILER +# echo Exclude list=${EXCLUDE_ACTIONS[@]} + name="$($COMPILER -E -DGENACTIONLIST "$f" 2>/dev/null| grep "ADD ACTION CLASS: " | sed "s/.*: //")" + name=${name//;/} + if included "$name"; then + pushd "$cdir">/dev/null + echo "#include \"$f\"">>"$OUT" + actlist+=" Action$name" + popd>/dev/null + fi + fi +done + +actlist=${actlist## } +actlist=${actlist%% } +actlist=${actlist// /,} +pushd "$cdir">/dev/null +echo "#define ACTLIST $actlist">>"$OUT" +popd>/dev/null diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 644922c..a6dcfd6 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,13 +1,18 @@ set(EXENAME odm) +set(ACTIONLIST ../include/actionlist.h) +set(GENALIST ${CMAKE_SOURCE_DIR}/scripts/genactionslist) find_library(netcdf netcdf REQUIRED) find_package(OpenMP REQUIRED) set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") -include_directories(../michlib/michlib) +file(GLOB srcs CONFIGURE_DEPENDS *.cpp) +add_executable(${EXENAME} ${srcs} ${ACTIONLIST}) +target_include_directories(${EXENAME} PRIVATE ../michlib/michlib ${CMAKE_CURRENT_BINARY_DIR}/../include) + +file(GLOB actfiles CONFIGURE_DEPENDS ../actions/action*.h ../actions-add/action*.h) +add_custom_command(OUTPUT ${ACTIONLIST} COMMAND ${GENALIST} ARGS "${CMAKE_CXX_COMPILER} -I$, -I>" ${ACTIONLIST} ${EXCLUDE_ACTIONS} DEPENDS ${GENALIST} ${actfiles}) -file(GLOB srcs *.cpp) -add_executable(${EXENAME} ${srcs}) target_link_libraries(${EXENAME} ${linker_options} ${netcdf} OpenMP::OpenMP_CXX teos) set_target_properties(${EXENAME} PROPERTIES POSITION_INDEPENDENT_CODE ON) install(TARGETS ${EXENAME})