diff options
Diffstat (limited to 'boost/process/env.hpp')
-rw-r--r-- | boost/process/env.hpp | 908 |
1 files changed, 454 insertions, 454 deletions
diff --git a/boost/process/env.hpp b/boost/process/env.hpp index 4362b0fe86..1080283129 100644 --- a/boost/process/env.hpp +++ b/boost/process/env.hpp @@ -1,502 +1,502 @@ -// Copyright (c) 2016 Klemens D. Morgenstern
-//
-// 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)
- -#ifndef BOOST_PROCESS_DETAIL_ENV_HPP_
-#define BOOST_PROCESS_DETAIL_ENV_HPP_
- -#include <boost/process/environment.hpp>
-#include <boost/none.hpp>
- -#if defined(BOOST_POSIX_API)
-#include <boost/process/detail/posix/env_init.hpp>
-#elif defined(BOOST_WINDOWS_API)
-#include <boost/process/detail/windows/env_init.hpp>
-#endif
- -/** \file boost/process/env.hpp
- *
- * This header which provides the `env` property. It allows the modification of the
- * environment the child process will run in, in a functional style.
- *
- * \xmlonly
-<programlisting>
-namespace boost {
- namespace process {
- <emphasis>unspecified</emphasis> <globalname alt="boost::process::env">env</globalname>;
- }
-}
-</programlisting>
- * \endxmlonly
- *
- * For additional information see the platform documentations:
- *
- * - [windows](https://msdn.microsoft.com/en-US/library/windows/desktop/ms682653.aspx)
- * - [posix](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html)
- *
- */
- - -namespace boost {
- -namespace process { namespace detail {
- - -template<typename Char>
-std::size_t make_env_string_size(const std::basic_string<Char> & ch)
-{
- return ch.size() + 1;
-}
- -template<typename Char>
-std::size_t make_env_string_size(const Char * ch)
-{
- std::size_t sz = 0;
- while (ch[sz] != null_char<Char>())
- sz++;
- - sz++;
- return sz;
-}
- -template<typename Char, typename Container>
-inline std::basic_string<Char> make_env_string(const Container & value)
-{
- std::size_t sz = 0;
- for (auto & v : value)
- sz += make_env_string_size(v);
- - std::basic_string<Char> s;
- s.reserve(sz); //+1 for ;, end doesn't have one.
- - for (auto & val : value)
- (s += val) += api::env_seperator<Char>();
- - s.resize(s.size() -1); //remove last ';'
- return s;
-}
- - -template<typename Char>
-struct env_set
-{
- using string_type = std::basic_string<Char>;
- string_type key;
- string_type value;
-};
- -template<typename Char>
-struct env_append
-{
- using string_type = std::basic_string<Char>;
- string_type key;
- string_type value;
-};
- - - -template<typename Char>
-struct env_reset
-{
- using string_type = std::basic_string<Char>;
- string_type key;
-};
- - -template<> struct is_wchar_t<env_set<wchar_t>> : std::true_type {};
-template<> struct is_wchar_t<env_append<wchar_t>> : std::true_type {};
-template<> struct is_wchar_t<env_reset<wchar_t>> : std::true_type {};
-template<> struct is_wchar_t<basic_environment<wchar_t>> : std::true_type {};
- - -template<>
-struct char_converter<char, env_set<wchar_t>>
-{
- static env_set<char> conv(const env_set<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_set<char>>
-{
- static env_set<wchar_t> conv(const env_set<char> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<char, env_append<wchar_t>>
-{
- static env_append<char> conv(const env_append<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_append<char>>
-{
- static env_append<wchar_t> conv(const env_append<char> & in)
- {
- return {::boost::process::detail::convert(in.key),
- ::boost::process::detail::convert(in.value)};
- }
-};
- -template<>
-struct char_converter<char, env_reset<wchar_t>>
-{
- static env_reset<char> conv(const env_reset<wchar_t> & in)
- {
- return {::boost::process::detail::convert(in.key)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_reset<char>>
-{
- static env_reset<wchar_t> conv(const env_reset<char> & in)
- {
- return {::boost::process::detail::convert(in.key)};
- }
-};
- - -template<typename Char>
-struct env_init
-{
- basic_environment<Char> env;
-};
- -template<>
-struct char_converter<char, env_init<wchar_t>>
-{
- static env_init<char> conv(const env_init<wchar_t> & in)
- {
- return {basic_environment<char>(in.env)};
- }
-};
- -template<>
-struct char_converter<wchar_t, env_init<char>>
-{
- static env_init<wchar_t> conv(const env_init<char> & in)
- {
- return {basic_environment<wchar_t>(in.env)};
- }
-};
- -template<>
-struct char_converter<char, basic_environment<wchar_t>>
-{
- static basic_environment<char> conv(const basic_environment<wchar_t> & in)
- {
- return { basic_environment<char>(in) };
- }
-};
- -template<>
-struct char_converter<wchar_t, basic_environment<char>>
-{
- static basic_environment<wchar_t> conv(const basic_environment<char> & in)
- {
- return { basic_environment<wchar_t>(in) };
- }
-};
- -template<typename Char>
-struct env_proxy
-{
- using string_type = std::basic_string<Char>;
- string_type key;
- - - env_set<Char> operator=(const string_type & value)
- {
- return {std::move(key), value};
- }
- env_set<Char> operator=(const std::vector<string_type> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- env_set<Char> operator=(const std::initializer_list<const Char*> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- - env_append<Char> operator+=(const string_type & value)
- {
- return {std::move(key), value};
- }
- env_append<Char> operator+=(const std::vector<string_type> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- env_append<Char> operator+=(const std::initializer_list<const Char*> & value)
- {
- return {std::move(key), make_env_string<Char>(value)};
- }
- env_reset<Char> operator=(boost::none_t)
- {
- return {std::move(key)};
- }
-};
- -struct env_
-{
- constexpr env_() {};
- - template<typename Char>
- env_set<Char> operator()(const std::basic_string<Char> & key,
- const std::basic_string<Char> & value) const
- {
- return {key, value};
- }
- template<typename Char>
- env_set<Char> operator()(const std::basic_string<Char> & key,
- const std::vector<std::basic_string<Char>> & value) const
- {
- return {key, make_env_string<Char>(value)};
- }
- template<typename Char>
- env_set<Char> operator()(const std::basic_string<Char> & key,
- const std::initializer_list<Char*> & value) const
- {
- return {key, make_env_string<Char>(value)};
- }
- template<typename Char>
- env_reset<Char> operator()(const std::basic_string<Char> & key, boost::none_t)
- {
- return {key};
- }
- template<typename Char>
- env_proxy<Char> operator[](const std::basic_string<Char> & key) const
- {
- return {key};
- }
- template<typename Char>
- env_proxy<Char> operator[](const Char* key) const
- {
- return {key};
- }
- template<typename Char>
- env_init<Char> operator()(const basic_environment<Char> & env) const
- {
- return {env};
- }
- template<typename Char>
- env_init<Char> operator= (const basic_environment<Char> & env) const
- {
- return {env};
- }
-};
- -template<typename Char>
-struct env_builder
-{
- basic_environment<Char> env;
- env_builder() : env{basic_native_environment<Char>()} {}
-
- void operator()(const basic_environment<Char> & e)
- {
- env = e;
- }
- - void operator()(env_init<Char> & ei)
- {
- env = std::move(ei.env);
- }
- void operator()(env_set<Char> & es)
- {
- env[es.key] = es.value;
- }
- void operator()(env_reset<Char> & es)
- {
- env.erase(es.key);
- }
- template<typename T>
- void operator()(env_append<T> & es)
- {
- env[es.key] += es.value;
- }
- - typedef api::env_init<Char> result_type;
- api::env_init<Char> get_initializer()
- {
- return api::env_init<Char>(std::move(env));
- }
-};
- -template<>
-struct initializer_builder<env_tag<char>>
-{
- typedef env_builder<char> type;
-};
- -template<>
-struct initializer_builder<env_tag<wchar_t>>
-{
- typedef env_builder<wchar_t> type;
-};
- -}
- -/**
- -The `env` property provides a functional way to modify the environment used by
-the child process. If none is passed the environment is inherited from the father
-process. Appending means that the environment will be interpreted as a ';' or ':'
-seperated list as used in `PATH`.
- -On both `posix` and `windows` the environment variables can be lists of strings,
-seperated by ';'. This is typically used for the `PATH` variable.
- -By default the environment will be inherited from the launching process,
-which is also true if environment are modified with this initializer.
- -\section env_details Details
- -\subsection env_operations Operations
- -\subsubsection env_set_var Setting variables
+// Copyright (c) 2016 Klemens D. Morgenstern +// +// 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) + +#ifndef BOOST_PROCESS_DETAIL_ENV_HPP_ +#define BOOST_PROCESS_DETAIL_ENV_HPP_ + +#include <boost/process/environment.hpp> +#include <boost/none.hpp> + +#if defined(BOOST_POSIX_API) +#include <boost/process/detail/posix/env_init.hpp> +#elif defined(BOOST_WINDOWS_API) +#include <boost/process/detail/windows/env_init.hpp> +#endif + +/** \file boost/process/env.hpp + * + * This header which provides the `env` property. It allows the modification of the + * environment the child process will run in, in a functional style. + * + * \xmlonly +<programlisting> +namespace boost { + namespace process { + <emphasis>unspecified</emphasis> <globalname alt="boost::process::env">env</globalname>; + } +} +</programlisting> + * \endxmlonly + * + * For additional information see the platform documentations: + * + * - [windows](https://msdn.microsoft.com/en-US/library/windows/desktop/ms682653.aspx) + * - [posix](http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html) + * + */ + + +namespace boost { + +namespace process { namespace detail { + + +template<typename Char> +std::size_t make_env_string_size(const std::basic_string<Char> & ch) +{ + return ch.size() + 1; +} + +template<typename Char> +std::size_t make_env_string_size(const Char * ch) +{ + std::size_t sz = 0; + while (ch[sz] != null_char<Char>()) + sz++; + + sz++; + return sz; +} + +template<typename Char, typename Container> +inline std::basic_string<Char> make_env_string(const Container & value) +{ + std::size_t sz = 0; + for (auto & v : value) + sz += make_env_string_size(v); + + std::basic_string<Char> s; + s.reserve(sz); //+1 for ;, end doesn't have one. + + for (auto & val : value) + (s += val) += api::env_seperator<Char>(); + + s.resize(s.size() -1); //remove last ';' + return s; +} + + +template<typename Char> +struct env_set +{ + using string_type = std::basic_string<Char>; + string_type key; + string_type value; +}; + +template<typename Char> +struct env_append +{ + using string_type = std::basic_string<Char>; + string_type key; + string_type value; +}; + + + +template<typename Char> +struct env_reset +{ + using string_type = std::basic_string<Char>; + string_type key; +}; + + +template<> struct is_wchar_t<env_set<wchar_t>> : std::true_type {}; +template<> struct is_wchar_t<env_append<wchar_t>> : std::true_type {}; +template<> struct is_wchar_t<env_reset<wchar_t>> : std::true_type {}; +template<> struct is_wchar_t<basic_environment<wchar_t>> : std::true_type {}; + + +template<> +struct char_converter<char, env_set<wchar_t>> +{ + static env_set<char> conv(const env_set<wchar_t> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<wchar_t, env_set<char>> +{ + static env_set<wchar_t> conv(const env_set<char> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<char, env_append<wchar_t>> +{ + static env_append<char> conv(const env_append<wchar_t> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<wchar_t, env_append<char>> +{ + static env_append<wchar_t> conv(const env_append<char> & in) + { + return {::boost::process::detail::convert(in.key), + ::boost::process::detail::convert(in.value)}; + } +}; + +template<> +struct char_converter<char, env_reset<wchar_t>> +{ + static env_reset<char> conv(const env_reset<wchar_t> & in) + { + return {::boost::process::detail::convert(in.key)}; + } +}; + +template<> +struct char_converter<wchar_t, env_reset<char>> +{ + static env_reset<wchar_t> conv(const env_reset<char> & in) + { + return {::boost::process::detail::convert(in.key)}; + } +}; + + +template<typename Char> +struct env_init +{ + basic_environment<Char> env; +}; + +template<> +struct char_converter<char, env_init<wchar_t>> +{ + static env_init<char> conv(const env_init<wchar_t> & in) + { + return {basic_environment<char>(in.env)}; + } +}; + +template<> +struct char_converter<wchar_t, env_init<char>> +{ + static env_init<wchar_t> conv(const env_init<char> & in) + { + return {basic_environment<wchar_t>(in.env)}; + } +}; + +template<> +struct char_converter<char, basic_environment<wchar_t>> +{ + static basic_environment<char> conv(const basic_environment<wchar_t> & in) + { + return { basic_environment<char>(in) }; + } +}; + +template<> +struct char_converter<wchar_t, basic_environment<char>> +{ + static basic_environment<wchar_t> conv(const basic_environment<char> & in) + { + return { basic_environment<wchar_t>(in) }; + } +}; + +template<typename Char> +struct env_proxy +{ + using string_type = std::basic_string<Char>; + string_type key; + + + env_set<Char> operator=(const string_type & value) + { + return {std::move(key), value}; + } + env_set<Char> operator=(const std::vector<string_type> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + env_set<Char> operator=(const std::initializer_list<const Char*> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + + env_append<Char> operator+=(const string_type & value) + { + return {std::move(key), value}; + } + env_append<Char> operator+=(const std::vector<string_type> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + env_append<Char> operator+=(const std::initializer_list<const Char*> & value) + { + return {std::move(key), make_env_string<Char>(value)}; + } + env_reset<Char> operator=(boost::none_t) + { + return {std::move(key)}; + } +}; + +struct env_ +{ + constexpr env_() {}; + + template<typename Char> + env_set<Char> operator()(const std::basic_string<Char> & key, + const std::basic_string<Char> & value) const + { + return {key, value}; + } + template<typename Char> + env_set<Char> operator()(const std::basic_string<Char> & key, + const std::vector<std::basic_string<Char>> & value) const + { + return {key, make_env_string<Char>(value)}; + } + template<typename Char> + env_set<Char> operator()(const std::basic_string<Char> & key, + const std::initializer_list<Char*> & value) const + { + return {key, make_env_string<Char>(value)}; + } + template<typename Char> + env_reset<Char> operator()(const std::basic_string<Char> & key, boost::none_t) + { + return {key}; + } + template<typename Char> + env_proxy<Char> operator[](const std::basic_string<Char> & key) const + { + return {key}; + } + template<typename Char> + env_proxy<Char> operator[](const Char* key) const + { + return {key}; + } + template<typename Char> + env_init<Char> operator()(const basic_environment<Char> & env) const + { + return {env}; + } + template<typename Char> + env_init<Char> operator= (const basic_environment<Char> & env) const + { + return {env}; + } +}; + +template<typename Char> +struct env_builder +{ + basic_environment<Char> env; + env_builder() : env{basic_native_environment<Char>()} {} + + void operator()(const basic_environment<Char> & e) + { + env = e; + } + + void operator()(env_init<Char> & ei) + { + env = std::move(ei.env); + } + void operator()(env_set<Char> & es) + { + env[es.key] = es.value; + } + void operator()(env_reset<Char> & es) + { + env.erase(es.key); + } + template<typename T> + void operator()(env_append<T> & es) + { + env[es.key] += es.value; + } + + typedef api::env_init<Char> result_type; + api::env_init<Char> get_initializer() + { + return api::env_init<Char>(std::move(env)); + } +}; + +template<> +struct initializer_builder<env_tag<char>> +{ + typedef env_builder<char> type; +}; + +template<> +struct initializer_builder<env_tag<wchar_t>> +{ + typedef env_builder<wchar_t> type; +}; + +} + +/** + +The `env` property provides a functional way to modify the environment used by +the child process. If none is passed the environment is inherited from the father +process. Appending means that the environment will be interpreted as a ';' or ':' +separated list as used in `PATH`. + +On both `posix` and `windows` the environment variables can be lists of strings, +separated by ';'. This is typically used for the `PATH` variable. + +By default the environment will be inherited from the launching process, +which is also true if environment are modified with this initializer. + +\section env_details Details + +\subsection env_operations Operations -To set a variable `id` the value `value` the following syntax can be used.
+\subsubsection env_set_var Setting variables -\code{.cpp}
-env[id] = value;
-env(id, value);
-\endcode
+To set a variable `id` the value `value` the following syntax can be used. -`std::initializer_list` is among the allowed types, so the following syntax is also possible.
+\code{.cpp} +env[id] = value; +env(id, value); +\endcode -\code{.cpp}
-env[id] = {value1, value2};
-env(id, {value1, value2});
-\endcode
+`std::initializer_list` is among the allowed types, so the following syntax is also possible. -\note Creates the variable if it does not exist.
+\code{.cpp} +env[id] = {value1, value2}; +env(id, {value1, value2}); +\endcode -The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`
-for both `id` and `value`.
+\note Creates the variable if it does not exist. -\paragraph id id
+The following lists contain possible value types, with `char_type` being either `char` or `wchar_t` +for both `id` and `value`. - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph id id -\paragraph env_set_var_value value
+ - `std::basic_string<char_type>` + - `const char_type *` - - `std::basic_string<char_type>`
- - `const char_type * `
- - `std::initializer_list<const char_type *>`
- - `std::vector<std::basic_string<char_type>>`
+\paragraph env_set_var_value value + - `std::basic_string<char_type>` + - `const char_type * ` + - `std::initializer_list<const char_type *>` + - `std::vector<std::basic_string<char_type>>` -\note Using `std::vector` or `std::initializer_list`
-\subsubsection env_append_var Append variables
+\note Using `std::vector` or `std::initializer_list` -Appending means, that a variable will be interpreted as a
-To append a variable `id` the value `value` the following syntax can be used:
+\subsubsection env_append_var Append variables -\code{.cpp}
-env[id] += value;
-\endcode
+Appending means, that a variable will be interpreted as a +To append a variable `id` the value `value` the following syntax can be used: -`std::initializer_list` is among the allowed types, so the following syntax is also possible.
+\code{.cpp} +env[id] += value; +\endcode -\code{.cpp}
-env[id] += {value1, value2};
-\endcode
+`std::initializer_list` is among the allowed types, so the following syntax is also possible. -\note Creates the variable if it does not exist.
+\code{.cpp} +env[id] += {value1, value2}; +\endcode -The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`
-for both `id` and `value`.
+\note Creates the variable if it does not exist. -\paragraph env_append_var_id id
+The following lists contain possible value types, with `char_type` being either `char` or `wchar_t` +for both `id` and `value`. - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph env_append_var_id id -\paragraph env_append_var_value value
+ - `std::basic_string<char_type>` + - `const char_type *` - - `std::basic_string<char_type>`
- - `const char_type *`
- - `std::initializer_list<const char_type *>`
- - `std::vector<std::basic_string<char_type>>`
+\paragraph env_append_var_value value + - `std::basic_string<char_type>` + - `const char_type *` + - `std::initializer_list<const char_type *>` + - `std::vector<std::basic_string<char_type>>` -\subsubsection env_reset Reset variables
-Reseting signle variables can be done in the following way:
+\subsubsection env_reset Reset variables -\code{.cpp}
-env[id] = boost::none;
-env(id, boost::none);
-\endcode
+Reseting signle variables can be done in the following way: -\note This does not set the value empty, but removes it from the list.
+\code{.cpp} +env[id] = boost::none; +env(id, boost::none); +\endcode -The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`:
+\note This does not set the value empty, but removes it from the list. -\paragraph env_reset_var_id id
+The following lists contain possible value types, with `char_type` being either `char` or `wchar_t`: - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph env_reset_var_id id -\subsubsection env_init Initialize the environment
+ - `std::basic_string<char_type>` + - `const char_type *` -The whole environment can be initialized from an object of type
-\xmlonly <classname>boost::process::environment</classname> \endxmlonly
+\subsubsection env_init Initialize the environment -\code{.cpp}
-env=env;
-env(env);
-\endcode
+The whole environment can be initialized from an object of type +\xmlonly <classname>boost::process::environment</classname> \endxmlonly -\note The passed `environment` can also be default-constructed to get an empty environment.
+\code{.cpp} +env=env; +env(env); +\endcode -\paragraph env_init_var_id id
+\note The passed `environment` can also be default-constructed to get an empty environment. - - `std::basic_string<char_type>`
- - `const char_type *`
+\paragraph env_init_var_id id -\paragraph env_init_var_value value
+ - `std::basic_string<char_type>` + - `const char_type *` - - `boost::process::basic_environment<char_type>`
+\paragraph env_init_var_value value -\subsection env_example Example
+ - `boost::process::basic_environment<char_type>` -\code{.cpp}
-spawn("b2", env["PATH"]+="F:/boost", env["SOME_VAR"]=boost::none, env["NEW_VAR"]="VALUE");
-\endcode
+\subsection env_example Example -If the overload style should be done by passing an instance of
-\xmlonly <classname>boost::process::environment</classname> \endxmlonly
-the above example would look like this.
+\code{.cpp} +spawn("b2", env["PATH"]+="F:/boost", env["SOME_VAR"]=boost::none, env["NEW_VAR"]="VALUE"); +\endcode -\code{.cpp}
-environment e = this_process::environment();
-e["PATH"] += "F:/boost";
-e.erase("SOME_VAR");
-e["NEW_VAR"] = "VALUE";
-spawn("b2", e);
-\endcode
+If the overload style should be done by passing an instance of +\xmlonly <classname>boost::process::environment</classname> \endxmlonly +the above example would look like this. -\warning Passing an empty environment will cause undefined behaviour.
+\code{.cpp} +environment e = this_process::environment(); +e["PATH"] += "F:/boost"; +e.erase("SOME_VAR"); +e["NEW_VAR"] = "VALUE"; +spawn("b2", e); +\endcode - */
-constexpr boost::process::detail::env_ env{};
+\warning Passing an empty environment will cause undefined behaviour. + */ +constexpr boost::process::detail::env_ env{}; -}}
-#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */
+}} + +#endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENV_HPP_ */ |