1 // Copyright 2011 Google Inc. 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are 6 // met: 7 // 8 // * Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // * Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // * Neither the name of Google Inc. nor the names of its contributors 14 // may be used to endorse or promote products derived from this software 15 // without specific prior written permission. 16 // 17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 #include "engine/context.hpp" 30 31 #include "utils/env.hpp" 32 #include "utils/format/macros.hpp" 33 #include "utils/fs/operations.hpp" 34 #include "utils/text/operations.ipp" 35 36 namespace fs = utils::fs; 37 namespace text = utils::text; 38 39 40 /// Internal implementation of a context. 41 struct engine::context::impl { 42 /// The current working directory. 43 fs::path _cwd; 44 45 /// The environment variables. 46 std::map< std::string, std::string > _env; 47 48 /// Constructor. 49 /// 50 /// \param cwd_ The current working directory. 51 /// \param env_ The environment variables. 52 impl(const fs::path& cwd_, 53 const std::map< std::string, std::string >& env_) : 54 _cwd(cwd_), 55 _env(env_) 56 { 57 } 58 59 /// Equality comparator. 60 /// 61 /// \param other The object to compare to. 62 /// 63 /// \return True if the two objects are equal; false otherwise. 64 bool 65 operator==(const impl& other) const 66 { 67 return _cwd == other._cwd && _env == other._env; 68 } 69 }; 70 71 72 /// Constructs a new context. 73 /// 74 /// \param cwd_ The current working directory. 75 /// \param env_ The environment variables. 76 engine::context::context(const fs::path& cwd_, 77 const std::map< std::string, std::string >& env_) : 78 _pimpl(new impl(cwd_, env_)) 79 { 80 } 81 82 83 /// Destructor. 84 engine::context::~context(void) 85 { 86 } 87 88 89 /// Constructs a new context based on the current environment. 90 engine::context 91 engine::context::current(void) 92 { 93 return context(fs::current_path(), utils::getallenv()); 94 } 95 96 97 /// Returns the current working directory of the context. 98 /// 99 /// \return A path. 100 const fs::path& 101 engine::context::cwd(void) const 102 { 103 return _pimpl->_cwd; 104 } 105 106 107 /// Returns the environment variables of the context. 108 /// 109 /// \return A variable name to variable value mapping. 110 const std::map< std::string, std::string >& 111 engine::context::env(void) const 112 { 113 return _pimpl->_env; 114 } 115 116 117 /// Equality comparator. 118 /// 119 /// \param other The other object to compare this one to. 120 /// 121 /// \return True if this object and other are equal; false otherwise. 122 bool 123 engine::context::operator==(const context& other) const 124 { 125 return *_pimpl == *other._pimpl; 126 } 127 128 129 /// Inequality comparator. 130 /// 131 /// \param other The other object to compare this one to. 132 /// 133 /// \return True if this object and other are different; false otherwise. 134 bool 135 engine::context::operator!=(const context& other) const 136 { 137 return !(*this == other); 138 } 139 140 141 /// Injects the object into a stream. 142 /// 143 /// \param output The stream into which to inject the object. 144 /// \param object The object to format. 145 /// 146 /// \return The output stream. 147 std::ostream& 148 engine::operator<<(std::ostream& output, const context& object) 149 { 150 output << F("context{cwd=%s, env=[") 151 % text::quote(object.cwd().str(), '\''); 152 153 const std::map< std::string, std::string >& env = object.env(); 154 bool first = true; 155 for (std::map< std::string, std::string >::const_iterator 156 iter = env.begin(); iter != env.end(); ++iter) { 157 if (!first) 158 output << ", "; 159 first = false; 160 161 output << F("%s=%s") % (*iter).first 162 % text::quote((*iter).second, '\''); 163 } 164 165 output << "]}"; 166 return output; 167 } 168