From f94dfd5329ff65556796fdef8df6d077a57911a3 Mon Sep 17 00:00:00 2001 From: g0dil <g0dil@wiback.org> Date: Sat, 7 Feb 2009 19:00:49 +0000 Subject: [PATCH] Socket/Protocols/INet: Implement address input streaming Utils/Logger: Implement dynmaic targets --- Socket/Protocols/INet/INet4Address.cc | 14 +++++ Socket/Protocols/INet/INet4Address.hh | 1 + Socket/Protocols/INet/INet6Address.cc | 13 +++++ Socket/Protocols/INet/INet6Address.hh | 1 + Socket/Protocols/INet/INetAddressing.cc | 44 ++++++++++++++ Socket/Protocols/INet/INetAddressing.cci | 16 ----- Socket/Protocols/INet/INetAddressing.hh | 2 + Utils/Console/Executor.cc | 1 + Utils/Logger/FileTarget.cc | 34 ++++++++++- Utils/Logger/FileTarget.hh | 11 +++- Utils/Logger/SyslogTarget.cc | 29 ++++++++++ Utils/Logger/SyslogTarget.hh | 29 ++++++++++ Utils/Logger/SyslogUDPTarget.cc | 74 ++++++++++++++++++++++++ Utils/Logger/SyslogUDPTarget.hh | 40 +++++++++++++ Utils/Logger/Target.cc | 34 ++++++++++- Utils/Logger/Target.cci | 5 ++ Utils/Logger/Target.ih | 8 +++ Utils/Termlib/Editor.cc | 1 - 18 files changed, 334 insertions(+), 23 deletions(-) diff --git a/Socket/Protocols/INet/INet4Address.cc b/Socket/Protocols/INet/INet4Address.cc index 0c100fb2d..d83c03442 100644 --- a/Socket/Protocols/INet/INet4Address.cc +++ b/Socket/Protocols/INet/INet4Address.cc @@ -161,6 +161,20 @@ prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4Address const & return os; } +prefix_ std::istream & senf::operator>>(std::istream & is, INet4Address & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet4Address::from_string(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "INet4Address.mpp" diff --git a/Socket/Protocols/INet/INet4Address.hh b/Socket/Protocols/INet/INet4Address.hh index e11982d39..e69c22459 100644 --- a/Socket/Protocols/INet/INet4Address.hh +++ b/Socket/Protocols/INet/INet4Address.hh @@ -175,6 +175,7 @@ namespace senf { \related INet4Address */ std::ostream & operator<<(std::ostream & os, INet4Address const & addr); + std::istream & operator>>(std::istream & os, INet4Address & addr); /** \brief CHeck INet4Address against a fixed network prefix diff --git a/Socket/Protocols/INet/INet6Address.cc b/Socket/Protocols/INet/INet6Address.cc index 6c76f7741..9aa52381e 100644 --- a/Socket/Protocols/INet/INet6Address.cc +++ b/Socket/Protocols/INet/INet6Address.cc @@ -105,6 +105,19 @@ prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6Address const & return os; } +prefix_ std::istream & senf::operator>>(std::istream & is, INet6Address & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet6Address::from_string(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} senf::INet6Address const senf::INet6Address::None; senf::INet6Address const senf::INet6Address::Loopback (0u,0u,0u,0u,0u,0u,0u,1u); diff --git a/Socket/Protocols/INet/INet6Address.hh b/Socket/Protocols/INet/INet6Address.hh index 98fb7262a..600ed57b3 100644 --- a/Socket/Protocols/INet/INet6Address.hh +++ b/Socket/Protocols/INet/INet6Address.hh @@ -283,6 +283,7 @@ namespace senf { \related INet6Address */ std::ostream & operator<<(std::ostream & os, INet6Address const & addr); + std::istream & operator>>(std::istream & is, INet6Address & addr); /** \brief Check INet6Address against a fixed network prefix diff --git a/Socket/Protocols/INet/INetAddressing.cc b/Socket/Protocols/INet/INetAddressing.cc index fdb4ee156..e224408f1 100644 --- a/Socket/Protocols/INet/INetAddressing.cc +++ b/Socket/Protocols/INet/INetAddressing.cc @@ -71,6 +71,26 @@ prefix_ senf::INet4SocketAddress::INet4SocketAddress(unsigned p) port(p); } +prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr) +{ + os << addr.address() << ":" << addr.port(); + return os; +} + +prefix_ std::istream & senf::operator>>(std::istream & is, INet4SocketAddress & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet4SocketAddress(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} + /////////////////////////////////////////////////////////////////////////// // senf::INet6SocketAddress @@ -131,6 +151,30 @@ prefix_ void senf::INet6SocketAddress::assignIface(std::string const & iface) } } +prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr) +{ + os << '[' << addr.address(); + std::string iface (addr.iface()); + if (! iface.empty()) + os << '%' << iface; + os << "]:" << addr.port(); + return os; +} + +prefix_ std::istream & senf::operator>>(std::istream & is, INet6SocketAddress & addr) +{ + std::string s; + if (!(is >> s)) + return is; + try { + addr = INet6SocketAddress(s); + } + catch (AddressException &) { + is.setstate(std::ios::failbit); + } + return is; +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "INetAddressing.mpp" diff --git a/Socket/Protocols/INet/INetAddressing.cci b/Socket/Protocols/INet/INetAddressing.cci index dc6bd0c53..556193846 100644 --- a/Socket/Protocols/INet/INetAddressing.cci +++ b/Socket/Protocols/INet/INetAddressing.cci @@ -70,12 +70,6 @@ prefix_ void senf::INet4SocketAddress::port(unsigned p) addr_.sin_port = htons(p); } -prefix_ std::ostream & senf::operator<<(std::ostream & os, INet4SocketAddress const & addr) -{ - os << addr.address() << ":" << addr.port(); - return os; -} - /////////////////////////////////////////////////////////////////////////// // senf::INet6SocketAddress @@ -143,16 +137,6 @@ prefix_ void senf::INet6SocketAddress::iface(std::string const & iface) assignIface(iface); } -prefix_ std::ostream & senf::operator<<(std::ostream & os, INet6SocketAddress const & addr) -{ - os << '[' << addr.address(); - std::string iface (addr.iface()); - if (! iface.empty()) - os << '%' << iface; - os << "]:" << addr.port(); - return os; -} - ///////////////////////////////cci.e/////////////////////////////////////// #undef prefix_ diff --git a/Socket/Protocols/INet/INetAddressing.hh b/Socket/Protocols/INet/INetAddressing.hh index f9327b524..a54b95e0b 100644 --- a/Socket/Protocols/INet/INetAddressing.hh +++ b/Socket/Protocols/INet/INetAddressing.hh @@ -109,6 +109,7 @@ namespace senf { \related INet4SocketAddress */ std::ostream & operator<<(std::ostream & os, INet4SocketAddress const & addr); + std::istream & operator>>(std::istream & is, INet4SocketAddress & addr); /** \brief IPv6 socket address @@ -202,6 +203,7 @@ namespace senf { \related INet6SocketAddress */ std::ostream & operator<<(std::ostream & os, INet6SocketAddress const & addr); + std::istream & operator>>(std::istream & is, INet6SocketAddress & addr); /// \addtogroup policy_impl_group /// @{ diff --git a/Utils/Console/Executor.cc b/Utils/Console/Executor.cc index 04cb75101..a228c331b 100644 --- a/Utils/Console/Executor.cc +++ b/Utils/Console/Executor.cc @@ -67,6 +67,7 @@ prefix_ std::string senf::console::Executor::cwdPath() { if (skipping()) return ""; + (void) cwd(); // ensure, cwd is live. return "/" + senf::stringJoin( senf::make_transform_range( boost::make_iterator_range(boost::next(cwd_.begin()), cwd_.end()), diff --git a/Utils/Logger/FileTarget.cc b/Utils/Logger/FileTarget.cc index 2baff33da..7cc2ad064 100644 --- a/Utils/Logger/FileTarget.cc +++ b/Utils/Logger/FileTarget.cc @@ -27,15 +27,26 @@ //#include "FileTarget.ih" // Custom includes +#include "../Console/Console.hh" //#include "FileTarget.mpp" #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// -prefix_ senf::log::FileTarget::FileTarget(std::string file) +prefix_ senf::log::FileTarget::FileTarget(std::string const & file) : ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(file, ofstream_t::member), file_(file) -{} +{ + consoleDir().add( "reopen", senf::membind( + static_cast<void (FileTarget::*)()>(&FileTarget::reopen), + this)) + .doc("Reopen logfile"); + consoleDir().add("reopen", senf::membind( + static_cast<void (FileTarget::*)(std::string const &)>(&FileTarget::reopen), + this)) + .arg("filename","new filename") + .overloadDoc("Reopen logfile under new name"); +} prefix_ void senf::log::FileTarget::reopen() { @@ -43,10 +54,27 @@ prefix_ void senf::log::FileTarget::reopen() ofstream_t::member.open(file_.c_str(), std::ofstream::app); } -prefix_ void senf::log::FileTarget::reopen(std::string file) +prefix_ void senf::log::FileTarget::reopen(std::string const & file) { file_ = file; reopen(); + // Rename console directory + console::DirectoryNode::ptr parent (consoleDir().node().parent()); + if (parent) + parent->add(file, consoleDir().node().unlink()); +} + +prefix_ senf::log::FileTarget::RegisterConsole::RegisterConsole() +{ + detail::TargetRegistry::instance().consoleDir().add("file-target",&RegisterConsole::create) + .arg("filename", "name of logfile") + .doc("Create new file target."); +} + +prefix_ void senf::log::FileTarget::RegisterConsole::create(std::string const & filename) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr<Target>(new FileTarget(filename))); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/FileTarget.hh b/Utils/Logger/FileTarget.hh index 5c4cc3429..ccd78fcbc 100644 --- a/Utils/Logger/FileTarget.hh +++ b/Utils/Logger/FileTarget.hh @@ -65,16 +65,23 @@ namespace log { ///\name Structors and default members ///@{ - explicit FileTarget(std::string file); ///< Construct FileTarget writing to \a file + explicit FileTarget(std::string const & filename); + ///< Construct FileTarget writing to \a file ///@} /////////////////////////////////////////////////////////////////////////// void reopen(); ///< Reopen %log after log-file rotation - void reopen(std::string file); ///< Reopen %log under a new name + void reopen(std::string const & file); ///< Reopen %log under a new name private: std::string file_; + + struct RegisterConsole { + RegisterConsole(); + static void create(std::string const & filename); + static RegisterConsole instance; + }; }; }} diff --git a/Utils/Logger/SyslogTarget.cc b/Utils/Logger/SyslogTarget.cc index 6b175c65f..7c8532100 100644 --- a/Utils/Logger/SyslogTarget.cc +++ b/Utils/Logger/SyslogTarget.cc @@ -27,6 +27,7 @@ //#include "SyslogTarget.ih" // Custom includes +#include "../Console/Console.hh" //#include "SyslogTarget.mpp" #define prefix_ @@ -45,6 +46,34 @@ prefix_ void senf::log::SyslogTarget::v_write(time_type timestamp, std::string c syslog(facility_ | LEVELMAP[level], "%s", message.c_str()); } +namespace senf { +namespace log { + + SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogTarget, LogFacility, + (AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG) + (USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5) + (LOCAL6)(LOCAL7)); + +}} + +prefix_ senf::log::SyslogTarget::RegisterConsole::RegisterConsole() +{ + namespace kw = senf::console::kw; + + detail::TargetRegistry::instance().consoleDir().add("syslog-target",&RegisterConsole::create) + .arg("facility", "syslog facility to send messages to. One of\n" + " AUTHPRIV, CRON, DAEMON, FTP, KERN, LPR, MAIL, NEWS, SYSLOG, USER,\n" + " UUCP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7", + kw::default_value = USER) + .doc("Create new syslog target."); +} + +prefix_ void senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr<Target>(new SyslogTarget(facility))); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "SyslogTarget.mpp" diff --git a/Utils/Logger/SyslogTarget.hh b/Utils/Logger/SyslogTarget.hh index d11e448a8..0049f59fd 100644 --- a/Utils/Logger/SyslogTarget.hh +++ b/Utils/Logger/SyslogTarget.hh @@ -92,6 +92,35 @@ namespace log { public: static int const LEVELMAP[8]; + + enum LogFacility { + AUTHPRIV = LOG_AUTHPRIV, + CRON = LOG_CRON, + DAEMON = LOG_DAEMON, + FTP = LOG_FTP, + KERN = LOG_KERN, + LOCAL0 = LOG_LOCAL0, + LOCAL1 = LOG_LOCAL1, + LOCAL2 = LOG_LOCAL2, + LOCAL3 = LOG_LOCAL3, + LOCAL4 = LOG_LOCAL4, + LOCAL5 = LOG_LOCAL5, + LOCAL6 = LOG_LOCAL6, + LOCAL7 = LOG_LOCAL7, + LPR = LOG_LPR, + MAIL = LOG_MAIL, + NEWS = LOG_NEWS, + SYSLOG = LOG_SYSLOG, + USER = LOG_USER, + UUCP = LOG_UUCP + }; + + private: + struct RegisterConsole { + RegisterConsole(); + static void create(LogFacility facility); + static RegisterConsole instance; + }; }; }} diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc index 03a055f89..af8da40c9 100644 --- a/Utils/Logger/SyslogUDPTarget.cc +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -30,6 +30,7 @@ #include <sstream> #include <boost/algorithm/string/trim.hpp> #include <boost/tokenizer.hpp> +#include "../Console/Console.hh" //#include "SyslogUDPTarget.mpp" #define prefix_ @@ -68,6 +69,79 @@ prefix_ void senf::log::SyslogUDPTarget::v_write(time_type timestamp, std::strin } } +namespace senf { +namespace log { + + SENF_CONSOLE_REGISTER_ENUM_MEMBER(SyslogUDPTarget, LogFacility, + (AUTHPRIV)(CRON)(DAEMON)(FTP)(KERN)(LPR)(MAIL)(NEWS)(SYSLOG) + (USER)(UUCP)(LOCAL0)(LOCAL1)(LOCAL2)(LOCAL3)(LOCAL4)(LOCAL5) + (LOCAL6)(LOCAL7)); + +}} + +prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole() +{ + namespace kw = senf::console::kw; + + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast<void (*)(INet4SocketAddress const &, LogFacility)>( + &RegisterConsole::create)) + .arg("address", "target address to send log messages to") + .arg("facility", "syslog facility to send messages to. One of\n" + " AUTHPRIV, CRON, DAEMON, FTP, KERN, LPR, MAIL, NEWS, SYSLOG, USER,\n" + " UUCP, LOCAL0, LOCAL1, LOCAL2, LOCAL3, LOCAL4, LOCAL5, LOCAL6, LOCAL7", + kw::default_value = USER) + .doc("Create new udp target. The {address} can be an IPv4 or IPv6 address. If the port\n" + "number is omitted, it defaults to the default syslog port 514."); + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast<void (*)(INet4Address const &, LogFacility)>( + &RegisterConsole::create)) + .arg("address") + .arg("facility", kw::default_value = USER); + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast<void (*)(INet6SocketAddress const &, LogFacility)>( + &RegisterConsole::create)) + .arg("address") + .arg("facility", kw::default_value = USER); + detail::TargetRegistry::instance().consoleDir().add( + "udp-target", static_cast<void (*)(INet6Address const &, LogFacility)>( + &RegisterConsole::create)) + .arg("address") + .arg("facility", kw::default_value = USER); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4SocketAddress const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4Address const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6SocketAddress const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); +} + +prefix_ void +senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6Address const & target, + LogFacility facility) +{ + detail::TargetRegistry::instance().dynamicTarget( + std::auto_ptr<Target>(new SyslogUDPTarget(target, facility))); +} + ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "SyslogUDPTarget.mpp" diff --git a/Utils/Logger/SyslogUDPTarget.hh b/Utils/Logger/SyslogUDPTarget.hh index c3d8b1521..e6f35ffc1 100644 --- a/Utils/Logger/SyslogUDPTarget.hh +++ b/Utils/Logger/SyslogUDPTarget.hh @@ -86,6 +86,8 @@ namespace log { include the \c PRI part but skip the \c HEADER part (which includes the timestamp and hostname) for better performance. We add a space after the \c PRI to force the syslog daemon to skip the \c HEADER part. + + \ingroup targets */ class SyslogUDPTarget : public Target, private detail::LogFormat @@ -124,6 +126,44 @@ namespace log { senf::ConnectedCommunicationPolicy, senf::WriteablePolicy>::policy > Handle; Handle handle_; + + public: + enum LogFacility { + AUTHPRIV = LOG_AUTHPRIV, + CRON = LOG_CRON, + DAEMON = LOG_DAEMON, + FTP = LOG_FTP, + KERN = LOG_KERN, + LOCAL0 = LOG_LOCAL0, + LOCAL1 = LOG_LOCAL1, + LOCAL2 = LOG_LOCAL2, + LOCAL3 = LOG_LOCAL3, + LOCAL4 = LOG_LOCAL4, + LOCAL5 = LOG_LOCAL5, + LOCAL6 = LOG_LOCAL6, + LOCAL7 = LOG_LOCAL7, + LPR = LOG_LPR, + MAIL = LOG_MAIL, + NEWS = LOG_NEWS, + SYSLOG = LOG_SYSLOG, + USER = LOG_USER, + UUCP = LOG_UUCP + }; + + private: + + struct RegisterConsole { + RegisterConsole(); + static void create(senf::INet4SocketAddress const & target, + LogFacility facility = USER); + static void create(senf::INet4Address const & target, + LogFacility facility = USER); + static void create(senf::INet6SocketAddress const & target, + LogFacility facility = USER); + static void create(senf::INet6Address const & target, + LogFacility facility = USER); + static RegisterConsole instance; + }; }; }} diff --git a/Utils/Logger/Target.cc b/Utils/Logger/Target.cc index a35fca6d8..7218a2415 100644 --- a/Utils/Logger/Target.cc +++ b/Utils/Logger/Target.cc @@ -241,12 +241,21 @@ prefix_ senf::log::detail::TargetRegistry::TargetRegistry() kw::default_value = "senf::log::Debug") .arg("area","area to write message to", kw::default_value = "senf::log::DefaultArea") - .arg("level", "log level", + .arg("level", "log level, one of:\n" + " VERBOSE, NOTICE, MESSAGE, IMPORTANT, CRITICAL, FATAL", kw::default_value = MESSAGE) .arg("message", "message to write") .doc("Write log message"); } +prefix_ senf::log::detail::TargetRegistry::~TargetRegistry() +{ + Targets::iterator i (dynamicTargets_.begin()); + Targets::iterator const i_end (dynamicTargets_.end()); + for (; i != i_end; ++i) + delete *i; +} + prefix_ void senf::log::detail::TargetRegistry::consoleAreas(std::ostream & os) { AreaRegistry::iterator i (AreaRegistry::instance().begin()); @@ -404,6 +413,15 @@ prefix_ void senf::log::Target::consoleList(std::ostream & os) /////////////////////////////////////////////////////////////////////////// // senf::log::detail::TargetRegistry +prefix_ void senf::log::detail::TargetRegistry::dynamicTarget(std::auto_ptr<Target> target) +{ + target->consoleDir().add("remove", boost::function<void ()>( + boost::bind( + &TargetRegistry::consoleRemoveTarget, this, target.get()))) + .doc("Remove target."); + dynamicTargets_.insert(target.release()); +} + prefix_ void senf::log::detail::TargetRegistry::registerTarget(Target * target, std::string const & name) { @@ -423,6 +441,13 @@ prefix_ void senf::log::detail::TargetRegistry::write(StreamBase const & stream, else area.write( TimeSource::now(), stream, level, msg ); } + +prefix_ void senf::log::detail::TargetRegistry::consoleRemoveTarget(Target * target) +{ + dynamicTargets_.erase(target); + delete target; +} + /////////////////////////////////////////////////////////////////////////// // namespace members @@ -434,6 +459,13 @@ prefix_ std::ostream & senf::log::operator<<(std::ostream & os, senf::log::Targe return os; } +////////////////////////////////////////////////////////////////////////// +// I need to put this here, otherwise the file target will not be registered +// if it is not used ... :-( + +senf::log::FileTarget::RegisterConsole senf::log::FileTarget::RegisterConsole::instance; +senf::log::SyslogTarget::RegisterConsole senf::log::SyslogTarget::RegisterConsole::instance; +senf::log::SyslogUDPTarget::RegisterConsole senf::log::SyslogUDPTarget::RegisterConsole::instance; ///////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ diff --git a/Utils/Logger/Target.cci b/Utils/Logger/Target.cci index 09c570669..7e02f9103 100644 --- a/Utils/Logger/Target.cci +++ b/Utils/Logger/Target.cci @@ -134,6 +134,11 @@ prefix_ bool senf::log::detail::TargetRegistry::fallbackRouting() return fallbackRouting_; } +prefix_ senf::console::ScopedDirectory<> & senf::log::detail::TargetRegistry::consoleDir() +{ + return consoleDir_(); +} + //////////////////////////////////////// // private members diff --git a/Utils/Logger/Target.ih b/Utils/Logger/Target.ih index bc48061c0..f926f8756 100644 --- a/Utils/Logger/Target.ih +++ b/Utils/Logger/Target.ih @@ -60,8 +60,13 @@ namespace detail { void routed(); bool fallbackRouting(); + senf::console::ScopedDirectory<> & consoleDir(); + + void dynamicTarget(std::auto_ptr<Target> target); + private: TargetRegistry(); + ~TargetRegistry(); void registerTarget(Target * target, std::string const & name); void unregisterTarget(Target * target); @@ -70,6 +75,7 @@ namespace detail { void consoleStreams(std::ostream & os); void consoleWrite(std::string const & stream, std::string const & area, Level level, std::string const & msg); + void consoleRemoveTarget(Target * target); typedef std::set<Target *> Targets; Targets targets_; @@ -77,6 +83,8 @@ namespace detail { bool fallbackRouting_; console::LazyDirectory consoleDir_; + + Targets dynamicTargets_; friend class senf::log::Target; friend class senf::singleton<TargetRegistry>; diff --git a/Utils/Termlib/Editor.cc b/Utils/Termlib/Editor.cc index f3a0c1971..8f434a6b3 100644 --- a/Utils/Termlib/Editor.cc +++ b/Utils/Termlib/Editor.cc @@ -433,7 +433,6 @@ prefix_ void senf::term::LineEditor::insert(std::string const & text) prefix_ void senf::term::LineEditor::pushHistory(std::string const & text) { if (! text.empty() - && (historyPoint_ == history_.size() || history_[historyPoint_] != text) && (history_.empty() || history_.back() != text)) { history_.push_back(text); while (history_.size() > MAX_HISTORY_SIZE) -- GitLab