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 36namespace fs = utils::fs; 37namespace text = utils::text; 38 39 40/// Internal implementation of a context. 41struct 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. 76engine::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. 84engine::context::~context(void) 85{ 86} 87 88 89/// Constructs a new context based on the current environment. 90engine::context 91engine::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. 100const fs::path& 101engine::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. 110const std::map< std::string, std::string >& 111engine::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. 122bool 123engine::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. 134bool 135engine::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. 147std::ostream& 148engine::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