aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-02-12 01:26:20 +0000
committerAvatar Ciaran McCreesh <ciaran.mccreesh@googlemail.com> 2009-02-12 01:26:20 +0000
commit5522cc551aaee176591b08546f368bb417c32f9e (patch)
tree975aa3b7325c820b51e35d1af4ee9dfc1bf7e2e4
parentb85660f6da793d06a304bf6d511c6b00344f20e2 (diff)
downloadpaludis-5522cc551aaee176591b08546f368bb417c32f9e.tar.gz
paludis-5522cc551aaee176591b08546f368bb417c32f9e.tar.xz
Add tee output manager
-rw-r--r--paludis/environments/paludis/output_managers.cc6
-rw-r--r--paludis/files.m41
-rw-r--r--paludis/output_manager_factory.cc7
-rw-r--r--paludis/output_manager_factory.hh12
-rw-r--r--paludis/standard_output_manager.cc5
-rw-r--r--paludis/standard_output_manager.hh6
-rw-r--r--paludis/tee_output_manager-fwd.hh34
-rw-r--r--paludis/tee_output_manager.cc121
-rw-r--r--paludis/tee_output_manager.hh62
-rw-r--r--paludis/util/tee_output_stream.cc59
-rw-r--r--paludis/util/tee_output_stream.hh54
11 files changed, 320 insertions, 47 deletions
diff --git a/paludis/environments/paludis/output_managers.cc b/paludis/environments/paludis/output_managers.cc
index 9ac7015..b5d29d8 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 e576687..a9ca87f 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 b332cf1..1c8c903 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 d6b78d4..ca8e045 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 e546057..cc6a305 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 b041620..0926d6f 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 0000000..a2af471
--- /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 0000000..2624029
--- /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 0000000..6003c55
--- /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 b0b74e5..00cb71f 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 f3a736c..1e319bd 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