Mercurial > hg > orthanc
changeset 2920:ad0e7def3338
Toolbox::SubstituteVariables and SystemToolbox::GetEnvironmentVariables
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 07 Nov 2018 11:13:30 +0100 |
parents | 2ca9cd064b15 |
children | 0a4428aad512 |
files | Core/SystemToolbox.cpp Core/SystemToolbox.h Core/Toolbox.cpp Core/Toolbox.h UnitTestsSources/UnitTestsMain.cpp |
diffstat | 5 files changed, 138 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/Core/SystemToolbox.cpp Tue Nov 06 15:41:21 2018 +0100 +++ b/Core/SystemToolbox.cpp Wed Nov 07 11:13:30 2018 +0100 @@ -38,6 +38,7 @@ #if defined(_WIN32) # include <windows.h> # include <process.h> // For "_spawnvp()" and "_getpid()" +# include <stdlib.h> // For "environ" #else # include <unistd.h> // For "execvp()" # include <sys/wait.h> // For "waitpid()" @@ -72,6 +73,51 @@ #include <boost/thread.hpp> +/*========================================================================= + The section below comes from the Boost 1.68.0 project: + https://github.com/boostorg/program_options/blob/boost-1.68.0/src/parsers.cpp + + Copyright Vladimir Prus 2002-2004. + Distributed under the Boost Software License, Version 1.0. + (See accompanying file LICENSE_1_0.txt + or copy at http://www.boost.org/LICENSE_1_0.txt) + =========================================================================*/ + +// The 'environ' should be declared in some cases. E.g. Linux man page says: +// (This variable must be declared in the user program, but is declared in +// the header file unistd.h in case the header files came from libc4 or libc5, +// and in case they came from glibc and _GNU_SOURCE was defined.) +// To be safe, declare it here. + +// It appears that on Mac OS X the 'environ' variable is not +// available to dynamically linked libraries. +// See: http://article.gmane.org/gmane.comp.lib.boost.devel/103843 +// See: http://lists.gnu.org/archive/html/bug-guile/2004-01/msg00013.html +#if defined(__APPLE__) && defined(__DYNAMIC__) +// The proper include for this is crt_externs.h, however it's not +// available on iOS. The right replacement is not known. See +// https://svn.boost.org/trac/boost/ticket/5053 +extern "C" +{ + extern char ***_NSGetEnviron(void); +} +# define environ (*_NSGetEnviron()) +#else +# if defined(__MWERKS__) +# include <crtl.h> +# else +# if !defined(_WIN32) || defined(__COMO_VERSION__) +extern char** environ; +# endif +# endif +#endif + + +/*========================================================================= + End of section from the Boost 1.68.0 project + =========================================================================*/ + + namespace Orthanc { static bool finish_; @@ -645,4 +691,23 @@ return MimeType_Binary; } } + + + void SystemToolbox::GetEnvironmentVariables(std::map<std::string, std::string>& env) + { + env.clear(); + + for (char **p = environ; *p != NULL; p++) + { + std::string v(*p); + size_t pos = v.find('='); + + if (pos != std::string::npos) + { + std::string key = v.substr(0, pos); + std::string value = v.substr(pos + 1); + env[key] = value; + } + } + } }
--- a/Core/SystemToolbox.h Tue Nov 06 15:41:21 2018 +0100 +++ b/Core/SystemToolbox.h Wed Nov 07 11:13:30 2018 +0100 @@ -43,6 +43,7 @@ #include "Enumerations.h" +#include <map> #include <vector> #include <string> #include <stdint.h> @@ -102,5 +103,7 @@ unsigned int GetHardwareConcurrency(); MimeType AutodetectMimeType(const std::string& path); + + void GetEnvironmentVariables(std::map<std::string, std::string>& env); } }
--- a/Core/Toolbox.cpp Tue Nov 06 15:41:21 2018 +0100 +++ b/Core/Toolbox.cpp Wed Nov 07 11:13:30 2018 +0100 @@ -1490,6 +1490,53 @@ #endif return s; } + + + namespace + { + // Anonymous namespace to avoid clashes between compilation modules + + class VariableFormatter + { + public: + typedef std::map<std::string, std::string> Dictionary; + + private: + const Dictionary& dictionary_; + + public: + VariableFormatter(const Dictionary& dictionary) : + dictionary_(dictionary) + { + } + + template<typename Out> + Out operator()(const boost::smatch& what, + Out out) const + { + Dictionary::const_iterator found = dictionary_.find(what[1]); + + if (found != dictionary_.end()) + { + const std::string& value = found->second; + out = std::copy(value.begin(), value.end(), out); + } + + return out; + } + }; + } + + + std::string Toolbox::SubstituteVariables(const std::string& source, + const std::map<std::string, std::string>& dictionary) + { + const boost::regex pattern("\\${(.*?)}"); + + VariableFormatter formatter(dictionary); + + return boost::regex_replace(source, pattern, formatter); + } }
--- a/Core/Toolbox.h Tue Nov 06 15:41:21 2018 +0100 +++ b/Core/Toolbox.h Wed Nov 07 11:13:30 2018 +0100 @@ -236,6 +236,9 @@ void FinalizeOpenSsl(); std::string GenerateUuid(); + + std::string SubstituteVariables(const std::string& source, + const std::map<std::string, std::string>& dictionary); } }
--- a/UnitTestsSources/UnitTestsMain.cpp Tue Nov 06 15:41:21 2018 +0100 +++ b/UnitTestsSources/UnitTestsMain.cpp Wed Nov 07 11:13:30 2018 +0100 @@ -1162,6 +1162,26 @@ } +TEST(Toolbox, SubstituteVariables) +{ + std::map<std::string, std::string> env; + env["NOPE"] = "nope"; + env["WORLD"] = "world"; + + ASSERT_EQ("Hello world\r\nWorld \r\nDone world\r\n", + Toolbox::SubstituteVariables( + "Hello ${WORLD}\r\nWorld ${HELLO}\r\nDone ${WORLD}\r\n", + env)); + + SystemToolbox::GetEnvironmentVariables(env); + ASSERT_TRUE(env.find("NOPE") == env.end()); + + // The "PATH" environment variable should always be available on + // machines running the unit tests + ASSERT_TRUE(env.find("PATH") != env.end()); +} + + int main(int argc, char **argv) { Logging::Initialize();