Exheredludis/paludis/tee_output_manager.cc
Saleem Abdulrasool 64ba7d5be8 modernize: use default method synthesis
Convert a number of destructors to default synthesized functions.  Try to
inline a few instances into the header.  It should be possible to inline all of
them, however, gcc seems to emit a number of warnings.  Furthermore, some of the
destructors are pure-virtualed, but provide an implementation.  Placing the
definition into the header causes ODR violations.
2016-08-06 11:58:04 -07:00

270 lines
11 KiB
C++

/* vim: set sw=4 sts=4 et foldmethod=syntax : */
/*
* Copyright (c) 2009, 2010, 2011, 2013 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/pimp-impl.hh>
#include <paludis/util/tee_output_stream.hh>
#include <paludis/util/sequence.hh>
#include <paludis/util/set.hh>
#include <paludis/util/wrapped_forward_iterator.hh>
#include <paludis/util/tokeniser.hh>
#include <paludis/util/indirect_iterator-impl.hh>
#include <vector>
#include <algorithm>
using namespace paludis;
namespace paludis
{
template <>
struct Imp<TeeOutputManager>
{
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > streams;
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > messages_streams;
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > stdout_streams;
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > stderr_streams;
TeeOutputStream stdout_stream;
TeeOutputStream stderr_stream;
Imp(
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > & s,
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > & ss,
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > & so,
const std::shared_ptr<const Sequence<std::shared_ptr<OutputManager> > > & se) :
streams(s),
messages_streams(ss),
stdout_streams(so),
stderr_streams(se)
{
}
};
}
TeeOutputManager::TeeOutputManager(
const std::shared_ptr<const OutputManagerSequence> & s,
const std::shared_ptr<const OutputManagerSequence> & ss) :
_imp(s, ss, nullptr, nullptr)
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
{
_imp->stdout_stream.add_stream(&(*i)->stdout_stream());
_imp->stderr_stream.add_stream(&(*i)->stderr_stream());
}
}
TeeOutputManager::TeeOutputManager(
const std::shared_ptr<const OutputManagerSequence> & s,
const std::shared_ptr<const OutputManagerSequence> & ss,
const std::shared_ptr<const OutputManagerSequence> & so,
const std::shared_ptr<const OutputManagerSequence> & se) :
_imp(s, ss, so, se)
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
{
_imp->stdout_stream.add_stream(&(*i)->stdout_stream());
_imp->stderr_stream.add_stream(&(*i)->stderr_stream());
}
for (OutputManagerSequence::ConstIterator i(_imp->stdout_streams->begin()), i_end(_imp->stdout_streams->end()) ;
i != i_end ; ++i)
_imp->stdout_stream.add_stream(&(*i)->stdout_stream());
for (OutputManagerSequence::ConstIterator i(_imp->stderr_streams->begin()), i_end(_imp->stderr_streams->end()) ;
i != i_end ; ++i)
_imp->stderr_stream.add_stream(&(*i)->stderr_stream());
}
TeeOutputManager::~TeeOutputManager() = default;
std::ostream &
TeeOutputManager::stdout_stream()
{
return _imp->stdout_stream;
}
std::ostream &
TeeOutputManager::stderr_stream()
{
return _imp->stderr_stream;
}
void
TeeOutputManager::message(const MessageType t, const std::string & m)
{
for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
i != i_end ; ++i)
(*i)->message(t, m);
}
void
TeeOutputManager::succeeded()
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
(*i)->succeeded();
for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
i != i_end ; ++i)
(*i)->succeeded();
for (OutputManagerSequence::ConstIterator i(_imp->stdout_streams->begin()), i_end(_imp->stdout_streams->end()) ;
i != i_end ; ++i)
(*i)->succeeded();
for (OutputManagerSequence::ConstIterator i(_imp->stderr_streams->begin()), i_end(_imp->stderr_streams->end()) ;
i != i_end ; ++i)
(*i)->succeeded();
}
void
TeeOutputManager::ignore_succeeded()
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
(*i)->ignore_succeeded();
for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
i != i_end ; ++i)
(*i)->ignore_succeeded();
for (OutputManagerSequence::ConstIterator i(_imp->stdout_streams->begin()), i_end(_imp->stdout_streams->end()) ;
i != i_end ; ++i)
(*i)->ignore_succeeded();
for (OutputManagerSequence::ConstIterator i(_imp->stderr_streams->begin()), i_end(_imp->stderr_streams->end()) ;
i != i_end ; ++i)
(*i)->ignore_succeeded();
}
void
TeeOutputManager::flush()
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
(*i)->flush();
for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
i != i_end ; ++i)
(*i)->flush();
for (OutputManagerSequence::ConstIterator i(_imp->stdout_streams->begin()), i_end(_imp->stdout_streams->end()) ;
i != i_end ; ++i)
(*i)->flush();
for (OutputManagerSequence::ConstIterator i(_imp->stderr_streams->begin()), i_end(_imp->stderr_streams->end()) ;
i != i_end ; ++i)
(*i)->flush();
}
bool
TeeOutputManager::want_to_flush() const
{
return indirect_iterator(_imp->streams->end()) != std::find_if(
indirect_iterator(_imp->streams->begin()), indirect_iterator(_imp->streams->end()),
std::bind(&OutputManager::want_to_flush, std::placeholders::_1)) ||
indirect_iterator(_imp->messages_streams->end()) != std::find_if(
indirect_iterator(_imp->messages_streams->begin()), indirect_iterator(_imp->messages_streams->end()),
std::bind(&OutputManager::want_to_flush, std::placeholders::_1)) ||
indirect_iterator(_imp->stdout_streams->end()) != std::find_if(
indirect_iterator(_imp->stdout_streams->begin()), indirect_iterator(_imp->stdout_streams->end()),
std::bind(&OutputManager::want_to_flush, std::placeholders::_1)) ||
indirect_iterator(_imp->stderr_streams->end()) != std::find_if(
indirect_iterator(_imp->stderr_streams->begin()), indirect_iterator(_imp->stderr_streams->end()),
std::bind(&OutputManager::want_to_flush, std::placeholders::_1));
}
void
TeeOutputManager::nothing_more_to_come()
{
for (OutputManagerSequence::ConstIterator i(_imp->streams->begin()), i_end(_imp->streams->end()) ;
i != i_end ; ++i)
(*i)->nothing_more_to_come();
for (OutputManagerSequence::ConstIterator i(_imp->messages_streams->begin()), i_end(_imp->messages_streams->end()) ;
i != i_end ; ++i)
(*i)->nothing_more_to_come();
for (OutputManagerSequence::ConstIterator i(_imp->stdout_streams->begin()), i_end(_imp->stdout_streams->end()) ;
i != i_end ; ++i)
(*i)->nothing_more_to_come();
for (OutputManagerSequence::ConstIterator i(_imp->stderr_streams->begin()), i_end(_imp->stderr_streams->end()) ;
i != i_end ; ++i)
(*i)->nothing_more_to_come();
}
const std::shared_ptr<const Set<std::string> >
TeeOutputManager::factory_managers()
{
std::shared_ptr<Set<std::string> > result(std::make_shared<Set<std::string>>());
result->insert("tee");
return result;
}
const std::shared_ptr<OutputManager>
TeeOutputManager::factory_create(
const OutputManagerFactory::KeyFunction & key_func,
const OutputManagerFactory::CreateChildFunction & create_child,
const OutputManagerFactory::ReplaceVarsFunc &)
{
std::shared_ptr<OutputManagerSequence> children(std::make_shared<OutputManagerSequence>());
std::shared_ptr<OutputManagerSequence> messages_children(std::make_shared<OutputManagerSequence>());
std::shared_ptr<OutputManagerSequence> stdout_children(std::make_shared<OutputManagerSequence>());
std::shared_ptr<OutputManagerSequence> stderr_children(std::make_shared<OutputManagerSequence>());
std::vector<std::string> children_keys;
tokenise_whitespace(key_func("children"), std::back_inserter(children_keys));
std::vector<std::string> messages_children_keys;
tokenise_whitespace(key_func("messages_children"), std::back_inserter(messages_children_keys));
std::vector<std::string> stdout_children_keys;
tokenise_whitespace(key_func("stdout_children"), std::back_inserter(stdout_children_keys));
std::vector<std::string> stderr_children_keys;
tokenise_whitespace(key_func("stderr_children"), std::back_inserter(stderr_children_keys));
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));
for (std::vector<std::string>::const_iterator c(messages_children_keys.begin()), c_end(messages_children_keys.end()) ;
c != c_end ; ++c)
messages_children->push_back(create_child(*c));
for (std::vector<std::string>::const_iterator c(stdout_children_keys.begin()), c_end(stdout_children_keys.end()) ;
c != c_end ; ++c)
stdout_children->push_back(create_child(*c));
for (std::vector<std::string>::const_iterator c(stderr_children_keys.begin()), c_end(stderr_children_keys.end()) ;
c != c_end ; ++c)
stderr_children->push_back(create_child(*c));
return std::make_shared<TeeOutputManager>(children, messages_children, stdout_children, stderr_children);
}
namespace paludis
{
template class Pimp<TeeOutputManager>;
}