diff options
Diffstat (limited to 'paludis')
-rw-r--r-- | paludis/environments/paludis/output_managers.cc | 6 | ||||
-rw-r--r-- | paludis/files.m4 | 1 | ||||
-rw-r--r-- | paludis/output_manager_factory.cc | 7 | ||||
-rw-r--r-- | paludis/output_manager_factory.hh | 12 | ||||
-rw-r--r-- | paludis/standard_output_manager.cc | 5 | ||||
-rw-r--r-- | paludis/standard_output_manager.hh | 6 | ||||
-rw-r--r-- | paludis/tee_output_manager-fwd.hh | 34 | ||||
-rw-r--r-- | paludis/tee_output_manager.cc | 121 | ||||
-rw-r--r-- | paludis/tee_output_manager.hh | 62 | ||||
-rw-r--r-- | paludis/util/tee_output_stream.cc | 59 | ||||
-rw-r--r-- | paludis/util/tee_output_stream.hh | 54 |
11 files changed, 320 insertions, 47 deletions
diff --git a/paludis/environments/paludis/output_managers.cc b/paludis/environments/paludis/output_managers.cc index 9ac7015d4..b5d29d87f 100644 --- a/paludis/environments/paludis/output_managers.cc +++ b/paludis/environments/paludis/output_managers.cc @@ -86,8 +86,10 @@ OutputManagers::create_named_output_manager(const std::string & s) const if (i == _imp->store.end()) throw PaludisConfigError("No output manager named '" + s + "' exists"); - return OutputManagerFactory::get_instance()->create(std::tr1::bind(&from_kv, i->second, - std::tr1::placeholders::_1)); + return OutputManagerFactory::get_instance()->create( + std::tr1::bind(&from_kv, i->second, std::tr1::placeholders::_1), + std::tr1::bind(&OutputManagers::create_named_output_manager, this, std::tr1::placeholders::_1) + ); } template class PrivateImplementationPattern<paludis_environment::OutputManagers>; diff --git a/paludis/files.m4 b/paludis/files.m4 index e576687fc..a9ca87f58 100644 --- a/paludis/files.m4 +++ b/paludis/files.m4 @@ -81,6 +81,7 @@ add(`stripper', `hh', `cc', `fwd', `test', `testscript' add(`syncer', `hh', `cc') add(`sync_task', `hh', `cc') add(`tasks_exceptions', `hh', `cc') +add(`tee_output_manager', `hh', `cc', `fwd') add(`unchoices_key', `hh', `cc', `fwd') add(`uninstall_list', `hh', `cc', `se', `test') add(`uninstall_task', `hh', `cc') diff --git a/paludis/output_manager_factory.cc b/paludis/output_manager_factory.cc index b332cf159..1c8c903f3 100644 --- a/paludis/output_manager_factory.cc +++ b/paludis/output_manager_factory.cc @@ -35,6 +35,7 @@ #include <list> #include <paludis/standard_output_manager.hh> +#include <paludis/tee_output_manager.hh> using namespace paludis; @@ -84,6 +85,7 @@ OutputManagerFactory::OutputManagerFactory() : { /* we might want to make this plugin loadable at some point */ add_manager(StandardOutputManager::factory_managers(), StandardOutputManager::factory_create); + add_manager(TeeOutputManager::factory_managers(), TeeOutputManager::factory_create); } OutputManagerFactory::~OutputManagerFactory() @@ -92,11 +94,12 @@ OutputManagerFactory::~OutputManagerFactory() const std::tr1::shared_ptr<OutputManager> OutputManagerFactory::create( - const KeyFunction & key_function + const KeyFunction & key_function, + const CreateChildFunction & create_child_function ) const { Context context("When creating output manager:"); - return fetch(_imp->keys, key_function("handler")).create_function()(key_function); + return fetch(_imp->keys, key_function("handler")).create_function()(key_function, create_child_function); } OutputManagerFactory::ConstIterator diff --git a/paludis/output_manager_factory.hh b/paludis/output_manager_factory.hh index d6b78d4c5..ca8e045fc 100644 --- a/paludis/output_manager_factory.hh +++ b/paludis/output_manager_factory.hh @@ -44,9 +44,12 @@ namespace paludis public: typedef std::tr1::function<std::string (const std::string &)> KeyFunction; + typedef std::tr1::function<const std::tr1::shared_ptr<OutputManager> ( + const std::string &)> CreateChildFunction; typedef std::tr1::function<const std::tr1::shared_ptr<OutputManager>( - const KeyFunction & + const KeyFunction &, + const CreateChildFunction & )> CreateFunction; /** @@ -56,9 +59,14 @@ namespace paludis * 'handler' key must return a value (e.g. 'standard'), which is used * to select the return type. Other key names are manager defined, * but typically include things like 'location' and 'keep_on_success'. + * + * \param create_child_function is used by, for example, + * TeeOutputManager to create child streams. Given a single string, + * this function returns the appropriate child. */ const std::tr1::shared_ptr<OutputManager> create( - const KeyFunction & key_function + const KeyFunction & key_function, + const CreateChildFunction & create_child_function ) const PALUDIS_ATTRIBUTE((warn_unused_result)); /** diff --git a/paludis/standard_output_manager.cc b/paludis/standard_output_manager.cc index e5460575a..cc6a3058c 100644 --- a/paludis/standard_output_manager.cc +++ b/paludis/standard_output_manager.cc @@ -63,7 +63,10 @@ StandardOutputManager::factory_managers() } const std::tr1::shared_ptr<OutputManager> -StandardOutputManager::factory_create(const std::tr1::function<std::string (const std::string &)> &) +StandardOutputManager::factory_create( + const OutputManagerFactory::KeyFunction &, + const OutputManagerFactory::CreateChildFunction & + ) { return make_shared_ptr(new StandardOutputManager); } diff --git a/paludis/standard_output_manager.hh b/paludis/standard_output_manager.hh index b041620ac..0926d6f0a 100644 --- a/paludis/standard_output_manager.hh +++ b/paludis/standard_output_manager.hh @@ -21,8 +21,9 @@ #define PALUDIS_GUARD_PALUDIS_STANDARD_OUTPUT_MANAGER_HH 1 #include <paludis/standard_output_manager-fwd.hh> -#include <paludis/output_manager.hh> #include <paludis/util/set-fwd.hh> +#include <paludis/output_manager.hh> +#include <paludis/output_manager_factory.hh> #include <tr1/memory> #include <tr1/functional> @@ -45,7 +46,8 @@ namespace paludis PALUDIS_ATTRIBUTE((warn_unused_result)); static const std::tr1::shared_ptr<OutputManager> factory_create( - const std::tr1::function<std::string (const std::string &)> &) + const OutputManagerFactory::KeyFunction &, + const OutputManagerFactory::CreateChildFunction &) PALUDIS_ATTRIBUTE((warn_unused_result)); }; } diff --git a/paludis/tee_output_manager-fwd.hh b/paludis/tee_output_manager-fwd.hh new file mode 100644 index 000000000..a2af47187 --- /dev/null +++ b/paludis/tee_output_manager-fwd.hh @@ -0,0 +1,34 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2009 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_TEE_OUTPUT_MANAGER_FWD_HH +#define PALUDIS_GUARD_PALUDIS_TEE_OUTPUT_MANAGER_FWD_HH 1 + +#include <paludis/util/sequence-fwd.hh> +#include <paludis/output_manager-fwd.hh> +#include <tr1/memory> + +namespace paludis +{ + class TeeOutputManager; + + typedef Sequence<std::tr1::shared_ptr<OutputManager> > OutputManagerSequence; +} + +#endif diff --git a/paludis/tee_output_manager.cc b/paludis/tee_output_manager.cc new file mode 100644 index 000000000..2624029d4 --- /dev/null +++ b/paludis/tee_output_manager.cc @@ -0,0 +1,121 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2009 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <paludis/tee_output_manager.hh> +#include <paludis/util/private_implementation_pattern-impl.hh> +#include <paludis/util/tee_output_stream.hh> +#include <paludis/util/sequence-impl.hh> +#include <paludis/util/set.hh> +#include <paludis/util/wrapped_forward_iterator.hh> +#include <paludis/util/make_shared_ptr.hh> +#include <paludis/util/tokeniser.hh> +#include <vector> + +using namespace paludis; + +namespace paludis +{ + template <> + struct Implementation<TeeOutputManager> + { + const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > streams; + TeeOutputStream stdout_stream; + TeeOutputStream stderr_stream; + + Implementation( + const std::tr1::shared_ptr<const Sequence<std::tr1::shared_ptr<OutputManager> > > & s) : + streams(s) + { + } + }; +} + +TeeOutputManager::TeeOutputManager( + const std::tr1::shared_ptr<const OutputManagerSequence> & s) : + PrivateImplementationPattern<TeeOutputManager>(new Implementation<TeeOutputManager>(s)) +{ + for (OutputManagerSequence::ConstIterator i(s->begin()), i_end(s->end()) ; + i != i_end ; ++i) + { + _imp->stdout_stream.add_stream(&(*i)->stdout_stream()); + _imp->stderr_stream.add_stream(&(*i)->stderr_stream()); + } +} + +TeeOutputManager::~TeeOutputManager() +{ +} + +std::ostream & +TeeOutputManager::stdout_stream() +{ + return _imp->stdout_stream; +} + +std::ostream & +TeeOutputManager::stderr_stream() +{ + return _imp->stderr_stream; +} + +void +TeeOutputManager::succeeded() +{ + for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ; + i != i_end ; ++i) + (*i)->succeeded(); +} + +void +TeeOutputManager::message(const MessageType t, const std::string & s) +{ + for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ; + i != i_end ; ++i) + (*i)->message(t, s); +} + +const std::tr1::shared_ptr<const Set<std::string> > +TeeOutputManager::factory_managers() +{ + std::tr1::shared_ptr<Set<std::string> > result(new Set<std::string>); + result->insert("tee"); + return result; +} + +const std::tr1::shared_ptr<OutputManager> +TeeOutputManager::factory_create( + const OutputManagerFactory::KeyFunction & key_func, + const OutputManagerFactory::CreateChildFunction & create_child) +{ + std::tr1::shared_ptr<OutputManagerSequence> children(new OutputManagerSequence); + + std::vector<std::string> children_keys; + tokenise_whitespace(key_func("children"), std::back_inserter(children_keys)); + if (children_keys.empty()) + throw ConfigurationError("No children specified for TeeOutputManager"); + + for (std::vector<std::string>::const_iterator c(children_keys.begin()), c_end(children_keys.end()) ; + c != c_end ; ++c) + children->push_back(create_child(*c)); + + return make_shared_ptr(new TeeOutputManager(children)); +} + +template class PrivateImplementationPattern<TeeOutputManager>; + diff --git a/paludis/tee_output_manager.hh b/paludis/tee_output_manager.hh new file mode 100644 index 000000000..6003c55e5 --- /dev/null +++ b/paludis/tee_output_manager.hh @@ -0,0 +1,62 @@ +/* vim: set sw=4 sts=4 et foldmethod=syntax : */ + +/* + * Copyright (c) 2009 Ciaran McCreesh + * + * This file is part of the Paludis package manager. Paludis is free software; + * you can redistribute it and/or modify it under the terms of the GNU General + * Public License version 2, as published by the Free Software Foundation. + * + * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 Temple + * Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef PALUDIS_GUARD_PALUDIS_TEE_OUTPUT_MANAGER_HH +#define PALUDIS_GUARD_PALUDIS_TEE_OUTPUT_MANAGER_HH 1 + +#include <paludis/tee_output_manager-fwd.hh> +#include <paludis/output_manager.hh> +#include <paludis/output_manager_factory.hh> +#include <paludis/util/set-fwd.hh> +#include <paludis/util/sequence-fwd.hh> +#include <paludis/util/private_implementation_pattern.hh> +#include <tr1/memory> +#include <tr1/functional> + +namespace paludis +{ + class PALUDIS_VISIBLE TeeOutputManager : + private PrivateImplementationPattern<TeeOutputManager>, + public OutputManager + { + public: + TeeOutputManager(const std::tr1::shared_ptr<const OutputManagerSequence> &); + ~TeeOutputManager(); + + virtual std::ostream & stdout_stream() PALUDIS_ATTRIBUTE((warn_unused_result)); + virtual std::ostream & stderr_stream() PALUDIS_ATTRIBUTE((warn_unused_result)); + + virtual void succeeded(); + virtual void message(const MessageType, const std::string &); + + static const std::tr1::shared_ptr<const Set<std::string> > factory_managers() + PALUDIS_ATTRIBUTE((warn_unused_result)); + + static const std::tr1::shared_ptr<OutputManager> factory_create( + const OutputManagerFactory::KeyFunction &, + const OutputManagerFactory::CreateChildFunction &) + PALUDIS_ATTRIBUTE((warn_unused_result)); + }; + +#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE + extern template class PrivateImplementationPattern<TeeOutputManager>; +#endif +} + +#endif diff --git a/paludis/util/tee_output_stream.cc b/paludis/util/tee_output_stream.cc index b0b74e56f..00cb71f47 100644 --- a/paludis/util/tee_output_stream.cc +++ b/paludis/util/tee_output_stream.cc @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2008 Ciaran McCreesh + * Copyright (c) 2008, 2009 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General @@ -18,6 +18,63 @@ */ #include <paludis/util/tee_output_stream.hh> +#include <paludis/util/private_implementation_pattern-impl.hh> +#include <list> using namespace paludis; +namespace paludis +{ + template <> + struct Implementation<TeeOutputStreamBuf> + { + std::list<std::ostream *> streams; + }; +} + +TeeOutputStreamBuf::TeeOutputStreamBuf() : + PrivateImplementationPattern<TeeOutputStreamBuf>(new Implementation<TeeOutputStreamBuf>) +{ +} + +TeeOutputStreamBuf::~TeeOutputStreamBuf() +{ +} + +TeeOutputStreamBuf::int_type +TeeOutputStreamBuf::overflow(int_type c) +{ + for (std::list<std::ostream *>::iterator i(_imp->streams.begin()), i_end(_imp->streams.end()) ; + i != i_end ; ++i) + (*i)->put(c); + return c; +} + +std::streamsize +TeeOutputStreamBuf::xsputn(const char * s, std::streamsize num) +{ + for (std::list<std::ostream *>::iterator i(_imp->streams.begin()), i_end(_imp->streams.end()) ; + i != i_end ; ++i) + (*i)->write(s, num); + return num; +} + +void +TeeOutputStreamBuf::add_stream(std::ostream * const s) +{ + _imp->streams.push_back(s); +} + +TeeOutputStream::TeeOutputStream() : + std::ostream(&buf) +{ +} + +void +TeeOutputStream::add_stream(std::ostream * const s) +{ + buf.add_stream(s); +} + +template class PrivateImplementationPattern<TeeOutputStreamBuf>; + diff --git a/paludis/util/tee_output_stream.hh b/paludis/util/tee_output_stream.hh index f3a736c63..1e319bd75 100644 --- a/paludis/util/tee_output_stream.hh +++ b/paludis/util/tee_output_stream.hh @@ -1,7 +1,7 @@ /* vim: set sw=4 sts=4 et foldmethod=syntax : */ /* - * Copyright (c) 2008 Ciaran McCreesh + * Copyright (c) 2008, 2009 Ciaran McCreesh * * This file is part of the Paludis package manager. Paludis is free software; * you can redistribute it and/or modify it under the terms of the GNU General @@ -22,55 +22,33 @@ #include <paludis/util/tee_output_stream-fwd.hh> #include <paludis/util/attributes.hh> +#include <paludis/util/private_implementation_pattern.hh> #include <ostream> namespace paludis { class PALUDIS_VISIBLE TeeOutputStreamBuf : - public std::streambuf + public std::streambuf, + private PrivateImplementationPattern<TeeOutputStreamBuf> { - private: - std::ostream * const s1; - std::ostream * const s2; - protected: virtual int_type - overflow(int_type c) - { - if (c != traits_type::eof()) - { - s1->put(c); - s2->put(c); - } - return c; - } + overflow(int_type c); virtual std::streamsize - xsputn(const char * s, std::streamsize num) - { - s1->write(s, num); - s2->write(s, num); - return num; - } + xsputn(const char * s, std::streamsize num); public: - TeeOutputStreamBuf(std::ostream * const b1, std::ostream * const b2) : - s1(b1), - s2(b2) - { - } + TeeOutputStreamBuf(); + ~TeeOutputStreamBuf(); + + void add_stream(std::ostream * const); }; class PALUDIS_VISIBLE TeeOutputStreamBase { protected: TeeOutputStreamBuf buf; - - public: - TeeOutputStreamBase(std::ostream * const b1, std::ostream * const b2) : - buf(b1, b2) - { - } }; class PALUDIS_VISIBLE TeeOutputStream : @@ -81,14 +59,16 @@ namespace paludis ///\name Basic operations ///\{ - TeeOutputStream(std::ostream * const b1, std::ostream * const b2) : - TeeOutputStreamBase(b1, b2), - std::ostream(&buf) - { - } + TeeOutputStream(); ///\} + + void add_stream(std::ostream * const); }; + +#ifdef PALUDIS_HAVE_EXTERN_TEMPLATE + extern template class PrivateImplementationPattern<TeeOutputStreamBuf>; +#endif } #endif |