diff --git a/modules/core/include/opencv2/core/utils/configuration.private.hpp b/modules/core/include/opencv2/core/utils/configuration.private.hpp index fa1b045178..b35f35e9d4 100644 --- a/modules/core/include/opencv2/core/utils/configuration.private.hpp +++ b/modules/core/include/opencv2/core/utils/configuration.private.hpp @@ -5,11 +5,17 @@ #ifndef OPENCV_CONFIGURATION_PRIVATE_HPP #define OPENCV_CONFIGURATION_PRIVATE_HPP +#include "opencv2/core/cvstd.hpp" +#include +#include + namespace cv { namespace utils { +typedef std::vector Paths; CV_EXPORTS bool getConfigurationParameterBool(const char* name, bool defaultValue); CV_EXPORTS size_t getConfigurationParameterSizeT(const char* name, size_t defaultValue); CV_EXPORTS cv::String getConfigurationParameterString(const char* name, const char* defaultValue); +CV_EXPORTS Paths getConfigurationParameterPaths(const char* name, const Paths &defaultValue = Paths()); }} // namespace diff --git a/modules/core/src/system.cpp b/modules/core/src/system.cpp index f1de60fd9a..ac1dc05d2d 100644 --- a/modules/core/src/system.cpp +++ b/modules/core/src/system.cpp @@ -43,6 +43,7 @@ #include "precomp.hpp" #include +#include #include #include @@ -1657,18 +1658,26 @@ static TLSData& getThreadIDTLS() } // namespace int utils::getThreadID() { return getThreadIDTLS().get()->id; } -bool utils::getConfigurationParameterBool(const char* name, bool defaultValue) + +class ParseError { -#ifdef NO_GETENV - const char* envValue = NULL; -#else - const char* envValue = getenv(name); -#endif - if (envValue == NULL) + std::string bad_value; +public: + ParseError(const std::string bad_value_) :bad_value(bad_value_) {} + std::string toString(const std::string ¶m) const { - return defaultValue; + std::ostringstream out; + out << "Invalid value for parameter " << param << ": " << bad_value; + return out.str(); } - cv::String value = envValue; +}; + +template +T parseOption(const std::string &); + +template<> +inline bool parseOption(const std::string & value) +{ if (value == "1" || value == "True" || value == "true" || value == "TRUE") { return true; @@ -1677,22 +1686,12 @@ bool utils::getConfigurationParameterBool(const char* name, bool defaultValue) { return false; } - CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str())); + throw ParseError(value); } - -size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultValue) +template<> +inline size_t parseOption(const std::string &value) { -#ifdef NO_GETENV - const char* envValue = NULL; -#else - const char* envValue = getenv(name); -#endif - if (envValue == NULL) - { - return defaultValue; - } - cv::String value = envValue; size_t pos = 0; for (; pos < value.size(); pos++) { @@ -1708,22 +1707,80 @@ size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultVal return v * 1024 * 1024; else if (suffixStr == "KB" || suffixStr == "Kb" || suffixStr == "kb") return v * 1024; - CV_Error(cv::Error::StsBadArg, cv::format("Invalid value for %s parameter: %s", name, value.c_str())); + throw ParseError(value); } -cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue) +template<> +inline cv::String parseOption(const std::string &value) +{ + return value; +} + +template<> +inline utils::Paths parseOption(const std::string &value) +{ + utils::Paths result; +#ifdef _WIN32 + const char sep = ';'; +#else + const char sep = ':'; +#endif + size_t start_pos = 0; + while (start_pos != std::string::npos) + { + const size_t pos = value.find(sep, start_pos); + const std::string one_piece(value, start_pos, pos == std::string::npos ? pos : pos - start_pos); + if (!one_piece.empty()) + result.push_back(one_piece); + start_pos = pos == std::string::npos ? pos : pos + 1; + } + return result; +} + +static inline const char * envRead(const char * name) { #ifdef NO_GETENV - const char* envValue = NULL; + CV_UNUSED(name); + return NULL; #else - const char* envValue = getenv(name); + return getenv(name); #endif - if (envValue == NULL) +} + +template +inline T read(const std::string & k, const T & defaultValue) +{ + try { - return defaultValue; + const char * res = envRead(k.c_str()); + if (res) + return parseOption(std::string(res)); } - cv::String value = envValue; - return value; + catch (const ParseError &err) + { + CV_Error(cv::Error::StsBadArg, err.toString(k)); + } + return defaultValue; +} + +bool utils::getConfigurationParameterBool(const char* name, bool defaultValue) +{ + return read(name, defaultValue); +} + +size_t utils::getConfigurationParameterSizeT(const char* name, size_t defaultValue) +{ + return read(name, defaultValue); +} + +cv::String utils::getConfigurationParameterString(const char* name, const char* defaultValue) +{ + return read(name, defaultValue); +} + +utils::Paths utils::getConfigurationParameterPaths(const char* name, const utils::Paths &defaultValue) +{ + return read(name, defaultValue); }