706 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			706 lines
		
	
	
		
			24 KiB
		
	
	
	
		
			C++
		
	
	
		
			Executable File
		
	
	
	
	
| // 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_ENVIRONMENT_HPP_
 | |
| #define BOOST_PROCESS_ENVIRONMENT_HPP_
 | |
| 
 | |
| #include <boost/process/detail/config.hpp>
 | |
| #include <boost/algorithm/string/split.hpp>
 | |
| #include <boost/algorithm/string/case_conv.hpp>
 | |
| #include <boost/iterator/transform_iterator.hpp>
 | |
| #include <boost/filesystem/path.hpp>
 | |
| 
 | |
| #if defined(BOOST_POSIX_API)
 | |
| #include <boost/process/detail/posix/environment.hpp>
 | |
| #elif defined(BOOST_WINDOWS_API)
 | |
| #include <boost/process/detail/windows/environment.hpp>
 | |
| #endif
 | |
| 
 | |
| namespace boost { namespace process {
 | |
| 
 | |
| namespace detail {
 | |
| 
 | |
| template<typename Char, typename Environment>
 | |
| struct const_entry
 | |
| {
 | |
|     using value_type    = Char ;
 | |
|     using pointer       = const value_type * ;
 | |
|     using string_type   = std::basic_string<value_type> ;
 | |
|     using range         = boost::iterator_range<pointer> ;
 | |
|     using environment_t = Environment ;
 | |
| 
 | |
|     std::vector<string_type> to_vector() const
 | |
|     {
 | |
|         if (_data == nullptr)
 | |
|             return std::vector<string_type>();
 | |
|         std::vector<string_type> data;
 | |
|         auto str = string_type(_data);
 | |
|         struct splitter
 | |
|         {
 | |
|             bool operator()(wchar_t w) const {return w == api::env_seperator<wchar_t>();}
 | |
|             bool operator()(char c)    const {return c == api::env_seperator<char>   ();}
 | |
|         } s;
 | |
|         boost::split(data, _data, s);
 | |
|         return data;
 | |
|     }
 | |
|     string_type to_string()              const
 | |
|     {
 | |
|         if (_data != nullptr)
 | |
|             return string_type(_data);
 | |
|         else
 | |
|             return string_type();
 | |
|     }
 | |
|     string_type get_name() const {return string_type(_name.begin(), _name.end());}
 | |
|     explicit const_entry(string_type&& name, pointer data, environment_t & env_) :
 | |
|         _name(std::move(name)), _data(data), _env(&env_) {}
 | |
| 
 | |
|     explicit const_entry(string_type &&name, environment_t & env) :
 | |
|         _name(std::move(name)), _data(nullptr), _env(&env) {}
 | |
|     const_entry(const const_entry&) = default;
 | |
|     const_entry& operator=(const const_entry&) = default;
 | |
| 
 | |
|     void reload()
 | |
|     {
 | |
|         auto p = _env->find(_name);
 | |
|         if (p == _env->end())
 | |
|             _data = nullptr;
 | |
|         else
 | |
|             _data = p->_data;
 | |
|         this->_env->reload();
 | |
| 
 | |
|     }
 | |
|     bool empty() const
 | |
|     {
 | |
|         return _data == nullptr;
 | |
|     }
 | |
| protected:
 | |
|     string_type _name;
 | |
|     pointer _data;
 | |
|     environment_t * _env;
 | |
| };
 | |
| 
 | |
| template<typename Char, typename Environment>
 | |
| struct entry : const_entry<Char, Environment>
 | |
| {
 | |
|     using father = const_entry<Char, Environment>;
 | |
|     using value_type    = typename father::value_type;
 | |
|     using string_type   = typename father::string_type;
 | |
|     using pointer       = typename father::pointer;
 | |
|     using environment_t = typename father::environment_t;
 | |
| 
 | |
|     explicit entry(string_type&& name, pointer data, environment_t & env) :
 | |
|         father(std::move(name), data, env) {}
 | |
| 
 | |
|     explicit entry(string_type &&name, environment_t & env_) :
 | |
|         father(std::move(name), env_) {}
 | |
| 
 | |
|     entry(const entry&) = default;
 | |
|     entry& operator=(const entry&) = default;
 | |
| 
 | |
|     void assign(const string_type &value)
 | |
|     {
 | |
|         this->_env->set(this->_name, value);
 | |
|         this->reload();
 | |
|     }
 | |
|     void assign(const std::vector<string_type> &value)
 | |
|     {
 | |
|         string_type data;
 | |
|         for (auto &v : value)
 | |
|         {
 | |
|             if (&v != &value.front())
 | |
|                 data += api::env_seperator<value_type>();
 | |
|             data += v;
 | |
|         }
 | |
|         this->_env->set(this->_name, data);
 | |
|         this->reload();
 | |
| 
 | |
|     }
 | |
|     void assign(const std::initializer_list<string_type> &value)
 | |
|     {
 | |
|         string_type data;
 | |
|         for (auto &v : value)
 | |
|         {
 | |
|             if (&v != &*value.begin())
 | |
|                 data += api::env_seperator<value_type>();
 | |
|             data += v;
 | |
|         }
 | |
|         this->_env->set(this->_name, data);
 | |
|         this->reload();
 | |
| 
 | |
|     }
 | |
|     void append(const string_type &value)
 | |
|     {
 | |
|         if (this->_data == nullptr)
 | |
|             this->_env->set(this->_name, value);
 | |
|         else
 | |
|         {
 | |
|             string_type st = this->_data;
 | |
|             this->_env->set(this->_name, st + api::env_seperator<value_type>() + value);
 | |
|         }
 | |
| 
 | |
| 
 | |
|         this->reload();
 | |
| 
 | |
|     }
 | |
|     void clear()
 | |
|     {
 | |
|         this->_env->reset(this->_name);
 | |
|         this->_env->reload();
 | |
|         this->_data = nullptr;
 | |
|     }
 | |
|     entry &operator=(const string_type & value)
 | |
|     {
 | |
|         assign(value);
 | |
|         return *this;
 | |
|     }
 | |
|     entry &operator=(const std::vector<string_type> & value)
 | |
|     {
 | |
|         assign(value);
 | |
|         return *this;
 | |
|     }
 | |
|     entry &operator=(const std::initializer_list<string_type> & value)
 | |
|     {
 | |
|         assign(value);
 | |
|         return *this;
 | |
|     }
 | |
|     entry &operator+=(const string_type & value)
 | |
|     {
 | |
|         append(value);
 | |
|         return *this;
 | |
|     }
 | |
| 
 | |
| };
 | |
| 
 | |
| 
 | |
| 
 | |
| template<typename Char, typename Environment>
 | |
| struct make_entry
 | |
| {
 | |
| 
 | |
|     make_entry(const make_entry&) = default;
 | |
|     make_entry& operator=(const make_entry&) = default;
 | |
| 
 | |
|     Environment *env;
 | |
|     make_entry(Environment & env) : env(&env) {};
 | |
|     entry<Char, Environment> operator()(const Char* data) const
 | |
|     {
 | |
|         auto p = data;
 | |
|         while ((*p != equal_sign<Char>()) && (*p != null_char<Char>()))
 | |
|                 p++;
 | |
|         auto name = std::basic_string<Char>(data, p);
 | |
|         p++; //go behind equal sign
 | |
| 
 | |
|         return entry<Char, Environment>(std::move(name), p, *env);
 | |
|     }
 | |
| };
 | |
| 
 | |
| template<typename Char, typename Environment>
 | |
| struct make_const_entry
 | |
| {
 | |
| 
 | |
|     make_const_entry(const make_const_entry&) = default;
 | |
|     make_const_entry& operator=(const make_const_entry&) = default;
 | |
| 
 | |
|     Environment *env;
 | |
|     make_const_entry(Environment & env) : env(&env) {};
 | |
|     const_entry<Char, Environment> operator()(const Char* data) const
 | |
|     {
 | |
|         auto p = data;
 | |
|         while ((*p != equal_sign<Char>()) && (*p != null_char<Char>()))
 | |
|                 p++;
 | |
|         auto name = std::basic_string<Char>(data, p);
 | |
|         p++; //go behind equal sign
 | |
| 
 | |
|         return const_entry<Char, Environment>(std::move(name), p, *env);
 | |
|     }
 | |
| };
 | |
| 
 | |
| }
 | |
| 
 | |
| #if !defined (BOOST_PROCESS_DOXYGEN)
 | |
| 
 | |
| template<typename Char, template <class> class Implementation = detail::api::basic_environment_impl>
 | |
| class basic_environment_impl : public Implementation<Char>
 | |
| {
 | |
|     Char** _get_end() const
 | |
|     {
 | |
|         auto p = this->_env_impl;
 | |
|         while (*p != nullptr)
 | |
|             p++;
 | |
| 
 | |
|         return p;
 | |
|     }
 | |
| public:
 | |
|     using string_type = std::basic_string<Char>;
 | |
|     using implementation_type = Implementation<Char>;
 | |
|     using base_type = basic_environment_impl<Char, Implementation>;
 | |
|     using       entry_maker = detail::make_entry<Char, base_type>;
 | |
|     using entry_type        = detail::entry     <Char, base_type>;
 | |
|     using const_entry_type  = detail::const_entry     <Char, const base_type>;
 | |
|     using const_entry_maker = detail::make_const_entry<Char, const base_type>;
 | |
| 
 | |
|     friend       entry_type;
 | |
|     friend const_entry_type;
 | |
| 
 | |
|     using iterator        = boost::transform_iterator<      entry_maker, Char**,       entry_type,       entry_type>;
 | |
|     using const_iterator  = boost::transform_iterator<const_entry_maker, Char**, const_entry_type, const_entry_type>;
 | |
|     using size_type       = std::size_t;
 | |
| 
 | |
|     iterator        begin()       {return       iterator(this->_env_impl,       entry_maker(*this));}
 | |
|     const_iterator  begin() const {return const_iterator(this->_env_impl, const_entry_maker(*this));}
 | |
|     const_iterator cbegin() const {return const_iterator(this->_env_impl, const_entry_maker(*this));}
 | |
| 
 | |
|     iterator        end()       {return       iterator(_get_end(),       entry_maker(*this));}
 | |
|     const_iterator  end() const {return const_iterator(_get_end(), const_entry_maker(*this));}
 | |
|     const_iterator cend() const {return const_iterator(_get_end(), const_entry_maker(*this));}
 | |
| 
 | |
|     iterator        find( const string_type& key )
 | |
|     {
 | |
|         auto p = this->_env_impl;
 | |
|         auto st1 = key + ::boost::process::detail::equal_sign<Char>();
 | |
|         while (*p != nullptr)
 | |
|         {
 | |
|             if (std::equal(st1.begin(), st1.end(), *p))
 | |
|                 break;
 | |
|             p++;
 | |
|         }
 | |
|         return iterator(p, entry_maker(*this));
 | |
|     }
 | |
|     const_iterator  find( const string_type& key ) const
 | |
|     {
 | |
|         auto p = this->_env_impl;
 | |
|         auto st1 = key + ::boost::process::detail::equal_sign<Char>();
 | |
|         while (*p != nullptr)
 | |
|         {
 | |
|             if (std::equal(st1.begin(), st1.end(), *p))
 | |
|                 break;
 | |
|             p++;
 | |
|         }
 | |
|         return const_iterator(p, const_entry_maker(*this));
 | |
|     }
 | |
| 
 | |
|     std::size_t count(const string_type & st) const
 | |
|     {
 | |
|         auto p = this->_env_impl;
 | |
|         auto st1 = st + ::boost::process::detail::equal_sign<Char>();
 | |
|         while (*p != nullptr)
 | |
|         {
 | |
|             if (std::equal(st1.begin(), st1.end(), *p))
 | |
|                 return 1u;
 | |
|             p++;
 | |
|         }
 | |
|         return 0u;
 | |
|     }
 | |
|     void erase(const string_type & id)
 | |
|     {
 | |
|         implementation_type::reset(id);
 | |
|         this->reload();
 | |
|     }
 | |
|     std::pair<iterator,bool> emplace(const string_type & id, const string_type & value)
 | |
|     {
 | |
|         auto f = find(id);
 | |
|         if (f == end())
 | |
|         {
 | |
|             implementation_type::set(id, value);
 | |
|             this->reload();
 | |
|             return std::pair<iterator, bool>(find(id), true);
 | |
|         }
 | |
|         else
 | |
|             return std::pair<iterator, bool>(f, false);
 | |
|     }
 | |
|     using implementation_type::implementation_type;
 | |
|     using implementation_type::operator=;
 | |
|     using native_handle_type = typename implementation_type::native_handle_type;
 | |
|     using implementation_type::native_handle;
 | |
|     //copy ctor if impl is copy-constructible
 | |
|     bool empty()
 | |
|     {
 | |
|         return *this->_env_impl == nullptr;
 | |
|     }
 | |
|     std::size_t size() const
 | |
|     {
 | |
|         return (_get_end() - this->_env_impl);
 | |
|     }
 | |
|     void clear()
 | |
|     {
 | |
|         std::vector<string_type> names;
 | |
|         names.resize(size());
 | |
|         std::transform(cbegin(), cend(), names.begin(), [](const const_entry_type & cet){return cet.get_name();});
 | |
| 
 | |
|         for (auto & nm : names)
 | |
|             implementation_type::reset(nm);
 | |
| 
 | |
|         this->reload();
 | |
|     }
 | |
| 
 | |
|     entry_type  at( const string_type& key )
 | |
|     {
 | |
|         auto f = find(key);
 | |
|         if (f== end())
 | |
|             throw std::out_of_range(key + " not found");
 | |
|         return *f;
 | |
|     }
 | |
|     const_entry_type at( const string_type& key ) const
 | |
|     {
 | |
|         auto f = find(key);
 | |
|         if (f== end())
 | |
|             throw std::out_of_range(key + " not found");
 | |
|         return *f;
 | |
|     }
 | |
|     entry_type operator[](const string_type & key)
 | |
|     {
 | |
|         auto p = find(key);
 | |
|         if (p != end())
 | |
|             return *p;
 | |
| 
 | |
|         return entry_type(string_type(key), *this);
 | |
|     }
 | |
| };
 | |
| #endif
 | |
| 
 | |
| #if defined(BOOST_PROCESS_DOXYGEN)
 | |
| /**Template representation of environments. It takes a character type (`char` or `wchar_t`)
 | |
|  * as template parameter to implement the environment
 | |
|  */
 | |
| template<typename Char>
 | |
| class basic_environment
 | |
| {
 | |
| 
 | |
| public:
 | |
|     typedef std::basic_string<Char> string_type;
 | |
|     typedef boost::transform_iterator<      entry_maker, Char**> iterator       ;
 | |
|     typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ;
 | |
|     typedef std::size_t                                             size_type      ;
 | |
| 
 | |
|     iterator       begin()        ; ///<Returns an iterator to the beginning
 | |
|     const_iterator begin()  const ; ///<Returns an iterator to the beginning
 | |
|     const_iterator cbegin() const ; ///<Returns an iterator to the beginning
 | |
| 
 | |
|     iterator       end()       ; ///<Returns an iterator to the end
 | |
|     const_iterator end()  const; ///<Returns an iterator to the end
 | |
|     const_iterator cend() const; ///<Returns an iterator to the end
 | |
| 
 | |
|     iterator        find( const string_type& key );            ///<Find a variable by its name
 | |
|     const_iterator  find( const string_type& key ) const;   ///<Find a variable by its name
 | |
| 
 | |
|     std::size_t count(const string_type & st) const; ///<Number of variables
 | |
|     void erase(const string_type & id); ///<Erase variable by id.
 | |
|     ///Emplace an environment variable.
 | |
|     std::pair<iterator,bool> emplace(const string_type & id, const string_type & value);
 | |
| 
 | |
|     ///Default constructor
 | |
|     basic_environment();
 | |
|     ///Copy constructor.
 | |
|     basic_environment(const basic_environment & );
 | |
|     ///Move constructor.
 | |
|     basic_environment(basic_environment && );
 | |
| 
 | |
|     ///Copy assignment.
 | |
|     basic_environment& operator=(const basic_environment & );
 | |
|     ///Move assignment.
 | |
|     basic_environment& operator=(basic_environment && );
 | |
| 
 | |
|     typedef typename detail::implementation_type::native_handle_type native_handle;
 | |
| 
 | |
|     ///Check if environment has entries.
 | |
|     bool empty();
 | |
|     ///Get the number of variables.
 | |
|     std::size_t size() const;
 | |
|     ///Clear the environment. @attention Use with care, passed environment cannot be empty.
 | |
|     void clear();
 | |
|     ///Get the entry with the key. Throws if it does not exist.
 | |
|     entry_type  at( const string_type& key );
 | |
|     ///Get the entry with the key. Throws if it does not exist.
 | |
|     const_entry_type at( const string_type& key ) const;
 | |
|     ///Get the entry with the given key. It creates the entry if it doesn't exist.
 | |
|     entry_type operator[](const string_type & key);
 | |
| 
 | |
|     /**Proxy class used for read access to members by [] or .at()
 | |
|      * @attention Holds a reference to the environment it was created from.
 | |
|      */
 | |
|     template<typename Char, typename Environment>
 | |
|     struct const_entry_type
 | |
|     {
 | |
|         typedef Char value_type;
 | |
|         typedef const value_type * pointer;
 | |
|         typedef std::basic_string<value_type> string_type;
 | |
|         typedef boost::iterator_range<pointer> range;
 | |
|         typedef Environment environment_t;
 | |
| 
 | |
|         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
 | |
|         std::vector<string_type> to_vector() const
 | |
|         ///Get the value as string.
 | |
|         string_type to_string()              const
 | |
|         ///Get the name of this entry.
 | |
|         string_type get_name() const {return string_type(_name.begin(), _name.end());}
 | |
|         ///Copy Constructor
 | |
|         const_entry(const const_entry&) = default;
 | |
|         ///Move Constructor
 | |
|         const_entry& operator=(const const_entry&) = default;
 | |
|         ///Check if the entry is empty.
 | |
|         bool empty() const;
 | |
|     };
 | |
| 
 | |
|     /**Proxy class used for read and write access to members by [] or .at()
 | |
|      * @attention Holds a reference to the environment it was created from.
 | |
|      */
 | |
|     template<typename Char, typename Environment>
 | |
|     struct entry_type
 | |
|     {
 | |
| 
 | |
|         typedef Char value_type;
 | |
|         typedef const value_type * pointer;
 | |
|         typedef std::basic_string<value_type> string_type;
 | |
|         typedef boost::iterator_range<pointer> range;
 | |
|         typedef Environment environment_t;
 | |
| 
 | |
|         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
 | |
|         std::vector<string_type> to_vector() const
 | |
|         ///Get the value as string.
 | |
|         string_type to_string()              const
 | |
|         ///Get the name of this entry.
 | |
|         string_type get_name() const {return string_type(_name.begin(), _name.end());}
 | |
|         ///Copy Constructor
 | |
|         entry(const entry&) = default;
 | |
|         ///Move Constructor
 | |
|         entry& operator=(const entry&) = default;
 | |
|         ///Check if the entry is empty.
 | |
|         bool empty() const;
 | |
| 
 | |
|         ///Assign a string to the value
 | |
|         void assign(const string_type &value);
 | |
|         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
 | |
|         void assign(const std::vector<string_type> &value);
 | |
|         ///Append a string to the end of the entry, it will separated by ';' or ':'.
 | |
|         void append(const string_type &value);
 | |
|         ///Reset the value
 | |
|         void clear();
 | |
|         ///Assign a string to the entry.
 | |
|         entry &operator=(const string_type & value);
 | |
|         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
 | |
|         entry &operator=(const std::vector<string_type> & value);
 | |
|         ///Append a string to the end of the entry, it will separated by ';' or ':'.
 | |
|         entry &operator+=(const string_type & value);
 | |
|     };
 | |
| 
 | |
| };
 | |
| 
 | |
| /**Template representation of the environment of this process. It takes a template
 | |
|  * as template parameter to implement the environment. All instances of this class
 | |
|  * refer to the same environment, but might not get updated if another one makes changes.
 | |
|  */
 | |
| template<typename Char>
 | |
| class basic_native_environment
 | |
| {
 | |
| 
 | |
| public:
 | |
|     typedef std::basic_string<Char> string_type;
 | |
|     typedef boost::transform_iterator<      entry_maker, Char**> iterator       ;
 | |
|     typedef boost::transform_iterator<const_entry_maker, Char**> const_iterator ;
 | |
|     typedef std::size_t                                             size_type      ;
 | |
| 
 | |
|     iterator       begin()        ; ///<Returns an iterator to the beginning
 | |
|     const_iterator begin()  const ; ///<Returns an iterator to the beginning
 | |
|     const_iterator cbegin() const ; ///<Returns an iterator to the beginning
 | |
| 
 | |
|     iterator       end()       ; ///<Returns an iterator to the end
 | |
|     const_iterator end()  const; ///<Returns an iterator to the end
 | |
|     const_iterator cend() const; ///<Returns an iterator to the end
 | |
| 
 | |
|     iterator        find( const string_type& key );            ///<Find a variable by its name
 | |
|     const_iterator  find( const string_type& key ) const;   ///<Find a variable by its name
 | |
| 
 | |
|     std::size_t count(const string_type & st) const; ///<Number of variables
 | |
|     void erase(const string_type & id); ///<Erase variable by id.
 | |
|     ///Emplace an environment variable.
 | |
|     std::pair<iterator,bool> emplace(const string_type & id, const string_type & value);
 | |
| 
 | |
|     ///Default constructor
 | |
|     basic_native_environment();
 | |
|     ///Move constructor.
 | |
|     basic_native_environment(basic_native_environment && );
 | |
|     ///Move assignment.
 | |
|     basic_native_environment& operator=(basic_native_environment && );
 | |
| 
 | |
|     typedef typename detail::implementation_type::native_handle_type native_handle;
 | |
| 
 | |
|     ///Check if environment has entries.
 | |
|     bool empty();
 | |
|     ///Get the number of variables.
 | |
|     std::size_t size() const;
 | |
|     ///Get the entry with the key. Throws if it does not exist.
 | |
|     entry_type  at( const string_type& key );
 | |
|     ///Get the entry with the key. Throws if it does not exist.
 | |
|     const_entry_type at( const string_type& key ) const;
 | |
|     ///Get the entry with the given key. It creates the entry if it doesn't exist.
 | |
|     entry_type operator[](const string_type & key);
 | |
| 
 | |
|     /**Proxy class used for read access to members by [] or .at()
 | |
|      * @attention Holds a reference to the environment it was created from.
 | |
|      */
 | |
|     template<typename Char, typename Environment>
 | |
|     struct const_entry_type
 | |
|     {
 | |
|         typedef Char value_type;
 | |
|         typedef const value_type * pointer;
 | |
|         typedef std::basic_string<value_type> string_type;
 | |
|         typedef boost::iterator_range<pointer> range;
 | |
|         typedef Environment environment_t;
 | |
| 
 | |
|         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
 | |
|         std::vector<string_type> to_vector() const
 | |
|         ///Get the value as string.
 | |
|         string_type to_string()              const
 | |
|         ///Get the name of this entry.
 | |
|         string_type get_name() const {return string_type(_name.begin(), _name.end());}
 | |
|         ///Copy Constructor
 | |
|         const_entry(const const_entry&) = default;
 | |
|         ///Move Constructor
 | |
|         const_entry& operator=(const const_entry&) = default;
 | |
|         ///Check if the entry is empty.
 | |
|         bool empty() const;
 | |
|     };
 | |
| 
 | |
|     /**Proxy class used for read and write access to members by [] or .at()
 | |
|      * @attention Holds a reference to the environment it was created from.
 | |
|      */
 | |
|     template<typename Char, typename Environment>
 | |
|     struct entry_type
 | |
|     {
 | |
| 
 | |
|         typedef Char value_type;
 | |
|         typedef const value_type * pointer;
 | |
|         typedef std::basic_string<value_type> string_type;
 | |
|         typedef boost::iterator_range<pointer> range;
 | |
|         typedef Environment environment_t;
 | |
| 
 | |
|         ///Split the entry by ";" or ":" and return it as a vector. Used by PATH.
 | |
|         std::vector<string_type> to_vector() const
 | |
|         ///Get the value as string.
 | |
|         string_type to_string()              const
 | |
|         ///Get the name of this entry.
 | |
|         string_type get_name() const {return string_type(_name.begin(), _name.end());}
 | |
|         ///Copy Constructor
 | |
|         entry(const entry&) = default;
 | |
|         ///Move Constructor
 | |
|         entry& operator=(const entry&) = default;
 | |
|         ///Check if the entry is empty.
 | |
|         bool empty() const;
 | |
| 
 | |
|         ///Assign a string to the value
 | |
|         void assign(const string_type &value);
 | |
|         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
 | |
|         void assign(const std::vector<string_type> &value);
 | |
|         ///Append a string to the end of the entry, it will separated by ';'  or ':'.
 | |
|         void append(const string_type &value);
 | |
|         ///Reset the value
 | |
|         void clear();
 | |
|         ///Assign a string to the entry.
 | |
|         entry &operator=(const string_type & value);
 | |
|         ///Assign a set of strings to the entry; they will be separated by ';' or ':'.
 | |
|         entry &operator=(const std::vector<string_type> & value);
 | |
|         ///Append a string to the end of the entry, it will separated by ';' or ':'.
 | |
|         entry &operator+=(const string_type & value);
 | |
|     };
 | |
| 
 | |
| };
 | |
| 
 | |
| #endif
 | |
| 
 | |
| ///Definition of the environment for the current process.
 | |
| template<typename Char>
 | |
| class basic_native_environment : public basic_environment_impl<Char, detail::api::native_environment_impl>
 | |
| {
 | |
| public:
 | |
|     using base_type = basic_environment_impl<Char, detail::api::native_environment_impl>;
 | |
|     using base_type::base_type;
 | |
|     using base_type::operator=;
 | |
| };
 | |
| 
 | |
| ///Type definition to hold a seperate environment.
 | |
| template<typename Char>
 | |
| class basic_environment : public basic_environment_impl<Char, detail::api::basic_environment_impl>
 | |
| {
 | |
| public:
 | |
|     using base_type = basic_environment_impl<Char, detail::api::basic_environment_impl>;
 | |
|     using base_type::base_type;
 | |
|     using base_type::operator=;
 | |
| };
 | |
| 
 | |
| 
 | |
| #if !defined(BOOST_NO_ANSI_APIS)
 | |
| ///Definition of the environment for the current process.
 | |
| typedef basic_native_environment<char>     native_environment;
 | |
| #endif
 | |
| ///Definition of the environment for the current process.
 | |
| typedef basic_native_environment<wchar_t> wnative_environment;
 | |
| 
 | |
| #if !defined(BOOST_NO_ANSI_APIS)
 | |
| ///Type definition to hold a seperate environment.
 | |
| typedef basic_environment<char>     environment;
 | |
| #endif
 | |
| ///Type definition to hold a seperate environment.
 | |
| typedef basic_environment<wchar_t> wenvironment;
 | |
| 
 | |
| }
 | |
| 
 | |
| ///Namespace containing information of the calling process.
 | |
| namespace this_process
 | |
| {
 | |
| 
 | |
| ///Definition of the native handle type.
 | |
| typedef ::boost::process::detail::api::native_handle_t native_handle_type;
 | |
| 
 | |
| #if !defined(BOOST_NO_ANSI_APIS)
 | |
| ///Definition of the environment for this process.
 | |
| using ::boost::process::native_environment;
 | |
| #endif
 | |
| ///Definition of the environment for this process.
 | |
| using ::boost::process::wnative_environment;
 | |
| 
 | |
| ///Get the process id of the current process.
 | |
| inline int get_id()                     { return ::boost::process::detail::api::get_id();}
 | |
| ///Get the native handle of the current process.
 | |
| inline native_handle_type native_handle()  { return ::boost::process::detail::api::native_handle();}
 | |
| #if !defined(BOOST_NO_ANSI_APIS)
 | |
| ///Get the enviroment of the current process.
 | |
| inline native_environment   environment() { return ::boost::process:: native_environment(); }
 | |
| #endif
 | |
| ///Get the enviroment of the current process.
 | |
| inline wnative_environment wenvironment() { return ::boost::process::wnative_environment(); }
 | |
| ///Get the path environment variable of the current process runs.
 | |
| inline std::vector<boost::filesystem::path> path()
 | |
| {
 | |
| #if defined(BOOST_WINDOWS_API)
 | |
|     const ::boost::process::wnative_environment ne{};
 | |
|     typedef typename ::boost::process::wnative_environment::const_entry_type value_type;
 | |
|     static constexpr auto id = L"PATH";
 | |
| #else
 | |
|     const ::boost::process::native_environment ne{};
 | |
|     typedef typename ::boost::process::native_environment::const_entry_type value_type;
 | |
|     static constexpr auto id = "PATH";
 | |
| #endif
 | |
| 
 | |
|     auto itr = std::find_if(ne.cbegin(), ne.cend(),
 | |
|             [&](const value_type & e)
 | |
|              {return id == ::boost::to_upper_copy(e.get_name(), ::boost::process::detail::process_locale());});
 | |
| 
 | |
|     if (itr == ne.cend())
 | |
|         return {};
 | |
| 
 | |
|     auto vec = itr->to_vector();
 | |
| 
 | |
|     std::vector<boost::filesystem::path> val;
 | |
|     val.resize(vec.size());
 | |
| 
 | |
|     std::copy(vec.begin(), vec.end(), val.begin());
 | |
| 
 | |
|     return val;
 | |
| }
 | |
| }
 | |
| }
 | |
| #endif /* INCLUDE_BOOST_PROCESS_DETAIL_ENVIRONMENT_HPP_ */
 |