// docker-finance | modern accounting for the power-user // // Copyright (C) 2021-2025 Aaron Fiore (Founder, Evergreen Crypto LLC) // // This program is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // This program is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License // along with this program. If not, see . //! \file //! \author Aaron Fiore (Founder, Evergreen Crypto LLC) //! \note File intended to be loaded into ROOT.cern framework / Cling interpreter //! \since docker-finance 1.1.0 #ifndef CONTAINER_SRC_ROOT_COMMON_UTILITY_HH_ #define CONTAINER_SRC_ROOT_COMMON_UTILITY_HH_ #include #include #include #include #include #include #include "./type.hh" //! \namespace dfi //! \since docker-finance 1.0.0 namespace dfi { //! \namespace dfi::common //! \brief Shared common functionality //! \since docker-finance 1.1.0 namespace common { //! \concept Exception //! \brief Exception type concept for `dfi` exceptions //! \ingroup cpp_common_impl //! \since docker-finance 1.1.0 template concept Exception = std::derived_from; //! \brief Throw exception using `dfi` exception type //! \param message Message to pass to exception type //! \param location Source location of exception //! \ingroup cpp_common_impl //! \since docker-finance 1.1.0 template inline void throw_ex( const std::string& message = {}, const std::source_location location = std::source_location::current()) { // TODO(unassigned): when throwing because of heap allocation std::string msg; msg += std::string(" \n\tFILE = ") + location.file_name(); msg += std::string(" \n\tFUNC = ") + location.function_name(); msg += std::string(" \n\tLINE = ") + location.line(); msg += std::string(" \n\tWHAT = ") + message; throw t_exception(msg); } //! \brief Throw exception using `dfi` exception type (but only on condition) //! \param condition If boolean condition is true, throw //! \param message Message to pass to exception type //! \param location Source location of exception //! \ingroup cpp_common_impl //! \since docker-finance 1.1.0 template inline void throw_ex_if( const bool condition, const std::string& message = {}, const std::source_location location = std::source_location::current()) { if (condition) { throw_ex(message, location); } } //! \brief Wrapper to ROOT Cling commands //! \ingroup cpp_common_impl //! \since docker-finance 1.0.0 class Command { public: Command() = default; ~Command() = default; Command(const Command&) = default; Command& operator=(const Command&) = default; Command(Command&&) = default; Command& operator=(Command&&) = default; private: static void cmd_handler(const std::initializer_list& command) { for (const auto& cmd : command) { std::cout << "Interpreting: '" << cmd << "'" << std::endl; gInterpreter->ProcessLine(cmd.c_str()); } } public: //! \brief Load given file path static void load(const std::string& path) { std::filesystem::path p(path); throw_ex_if( !std::filesystem::exists(p), "'" + path + "' does not exist!"); throw_ex_if( !std::filesystem::is_regular_file(p), "'" + path + "' is not a regular file!"); std::string cmd{".L " + path}; Command::cmd_handler({cmd}); } //! \brief Load given file paths static void load(const std::initializer_list& commands) { for (const auto& cmd : commands) Command::load(cmd); } // TODO(afiore): unload }; //! \brief Get ROOT environment variable //! \param var ROOT variable //! \note ROOT environment variables include shell (and shell caller) environment //! \since docker-finance 1.0.0 std::string get_env(const std::string& var) { const auto* env = gSystem->Getenv(var.c_str()); throw_ex_if( !env, "'" + var + "' is not set or is unavailable"); return std::string{env}; } //! \brief Execute command in shell //! \param cmd Shell command [args] //! \returns Return value of command //! \since docker-finance 1.0.0 int exec(const std::string& cmd) { return gSystem->Exec(cmd.c_str()); } //! \brief Make current timestamp //! \return timestamp in "yyyy-mm-ddThh:mm:ssZ" format //! \since docker-finance 1.0.0 std::string make_timestamp() { const std::time_t t{std::time({})}; std::vector time(std::size("yyyy-mm-ddThh:mm:ssZ")); std::strftime(time.data(), time.size(), "%FT%TZ", std::gmtime(&t)); return std::string{time.data()}; } } // namespace common } // namespace dfi #endif // CONTAINER_SRC_ROOT_COMMON_UTILITY_HH_ // # vim: sw=2 sts=2 si ai et