From: g0dil Date: Tue, 10 Feb 2009 15:12:10 +0000 (+0000) Subject: Utils/Console: Parser based character classifiers X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=4195e3fc4bb545f2f7921396e2aec77edaa8c8c3;p=senf.git Utils/Console: Parser based character classifiers Utils/Logger: Quote filename for console directory in FileTarget Utils/Logger: Add directory node return value to syslog-target and udp-target console commands git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@1114 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Utils/Console/Executor.hh b/Utils/Console/Executor.hh index 540472d..6a950f0 100644 --- a/Utils/Console/Executor.hh +++ b/Utils/Console/Executor.hh @@ -108,16 +108,17 @@ namespace console { /**< if autocomplete is enabled, path components which can be uniquely completed will be completed automatically. Disabled by default (but enabled - automatically by the interactive console) void - autocomplete(bool v). */ + automatically by the interactive console). */ Executor & autocomplete(bool v); ///< Set autocomplete status /**< \see autocomplete() */ + DirectoryNode & chroot() const; ///< Get root node /**< The root node defaults to senf::console::root(). If changed, all path references are relative to this node and objects outside that tree cannot be accessed. */ + Executor & chroot(DirectoryNode & node); ///< chroot into given directory /**< After this call, all path's are interpreted relative to \a node and only nodes in the tree rooted at \a node diff --git a/Utils/Console/Parse.cc b/Utils/Console/Parse.cc index dece5df..65dcaf3 100644 --- a/Utils/Console/Parse.cc +++ b/Utils/Console/Parse.cc @@ -393,7 +393,35 @@ senf::console::CommandParser::parseIncremental(std::string const & commands, Cal parseLoop(commands.begin(), commands.end(), "", cb) ); } -///////////////////////////////cc.e//////////////////////////////////////// +/////////////////////////////////////////////////////////////////////////// +// Character sets + +prefix_ bool senf::console::CommandParser::isSpecialChar(char ch) +{ + return Impl::Grammar::special_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isPunctuationChar(char ch) +{ + return Impl::Grammar::punctuation_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isSpaceChar(char ch) +{ + return Impl::Grammar::space_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isInvalidChar(char ch) +{ + return Impl::Grammar::invalid_p.test(ch); +} + +prefix_ bool senf::console::CommandParser::isWordChar(char ch) +{ + return Impl::Grammar::word_p.test(ch); +} + +/////////////////////////////cc.e//////////////////////////////////////// #undef prefix_ //#include "Parse.mpp" diff --git a/Utils/Console/Parse.hh b/Utils/Console/Parse.hh index 5e8b0ac..7afbaa1 100644 --- a/Utils/Console/Parse.hh +++ b/Utils/Console/Parse.hh @@ -615,6 +615,12 @@ namespace console { to be terminated explicitly. This means, that the last ';' is \e not optional in this case. */ + static bool isSpecialChar(char ch); ///< Check, if \a ch is a special character + static bool isPunctuationChar(char ch); ///< Check, if \a ch is a punctuation character + static bool isSpaceChar(char ch); ///< Check, if \a ch is a space character + static bool isInvalidChar(char ch); ///< Check, if \a ch is an invalid character + static bool isWordChar(char ch); ///< Check, if \a ch is a word character + /** \brief Exception thrown when the parser detects an error */ struct ParserErrorException : public SyntaxErrorException { explicit ParserErrorException(std::string const & msg) : SyntaxErrorException(msg) {} }; diff --git a/Utils/Console/Parse.ih b/Utils/Console/Parse.ih index 38b9fc9..4f0569f 100644 --- a/Utils/Console/Parse.ih +++ b/Utils/Console/Parse.ih @@ -78,6 +78,16 @@ namespace detail { ParseDispatcher & dispatcher; + ////////////////////////////////////////////////////////////////////////// + // charachter sets + + static boost::spirit::chset<> special_p; + static boost::spirit::chset<> punctuation_p; + static boost::spirit::chset<> space_p; + static boost::spirit::chset<> invalid_p; + static boost::spirit::chset<> word_p; + static boost::spirit::distinct_parser<> keyword_p; + /////////////////////////////////////////////////////////////////////////// // Errors @@ -104,33 +114,8 @@ namespace detail { punctuation, hexbyte, balanced_tokens, simple_argument, complex_argument, builtin, skip, statement, relpath, abspath, arguments, group_start, group_close, statement_end, opt_path; - boost::spirit::chset<> special_p, punctuation_p, space_p, invalid_p, word_p; - boost::spirit::distinct_parser<> keyword_p; - - definition(CommandGrammar const & self) : - - // Characters with a special meaning within the parser - special_p ("/(){};\""), - - // Additional characters which are returned as punctuation tokens - // (only allowed within '()'). - punctuation_p (",="), - - // Whitespace characters - space_p (" \t\n\r"), - - // Invalid characters: All chars below \x20 (space) which are not space_p - // (don't put a \0 in the chset<> argument *string* ...) - invalid_p ( (boost::spirit::chset<>('\0') - | boost::spirit::chset<>("\x01-\x20")) - space_p ), - - // Valid word characters - word_p ( - boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p), - - // Keywords must not be followed by a word char or '/' - keyword_p ( word_p | boost::spirit::ch_p('/') ) + definition(CommandGrammar const & self) { using namespace boost::spirit; using namespace ::phoenix; @@ -203,14 +188,14 @@ namespace detail { ; builtin - = keyword_p("cd") + = self.keyword_p("cd") >> path_expected(path) >> eps_p [ bind(&PD::builtin_cd)(d_, path_) ] - | keyword_p("ls") + | self.keyword_p("ls") >> ! path >> eps_p [ bind(&PD::builtin_ls)(d_, path_) ] - | keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ] - | keyword_p("help") + | self.keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ] + | self.keyword_p("help") >> ! path >> eps_p [ bind(&PD::builtin_help)(d_, path_) ] ; @@ -316,7 +301,7 @@ namespace detail { | ch_p(';') [ token_ = construct_( Token::CommandTerminator, ";") ] - | punctuation_p [ token_ = construct_( + | self.punctuation_p [ token_ = construct_( Token::OtherPunctuation, construct_(1u, arg1)) ] ; @@ -324,7 +309,7 @@ namespace detail { word // Returns value in context.token = lexeme_d [ - (+ word_p) [ str_ = construct_(arg1, arg2) ] + (+ self.word_p) [ str_ = construct_(arg1, arg2) ] ] >> eps_p [ token_ = construct_( Token::Word, @@ -347,7 +332,7 @@ namespace detail { ; skip - = space_p | comment_p('#') + = self.space_p | comment_p('#') ; /////////////////////////////////////////////////////////////////// @@ -381,6 +366,19 @@ namespace detail { }; }; + template boost::spirit::chset<> CommandGrammar::special_p ( + "/(){};\""); + template boost::spirit::chset<> CommandGrammar::punctuation_p ( + ",="); + template boost::spirit::chset<> CommandGrammar::space_p ( + " \t\n\r"); + template boost::spirit::chset<> CommandGrammar::invalid_p ( + (boost::spirit::chset<>('\0') | boost::spirit::chset<>("\x01-\x20")) - space_p ); + template boost::spirit::chset<> CommandGrammar::word_p ( + boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p); + template boost::spirit::distinct_parser<> CommandGrammar::keyword_p ( + word_p | boost::spirit::ch_p('/')); + #endif }}} diff --git a/Utils/Logger/FileTarget.cc b/Utils/Logger/FileTarget.cc index 52ebaf8..e15b3e8 100644 --- a/Utils/Logger/FileTarget.cc +++ b/Utils/Logger/FileTarget.cc @@ -33,8 +33,21 @@ #define prefix_ ///////////////////////////////cc.p//////////////////////////////////////// +namespace { + + std::string quoteFilename(std::string filename) + { + for (std::string::iterator i (filename.begin()); i != filename.end(); ++i) + if (! senf::console::CommandParser::isWordChar(*i)) + *i = '_'; + return filename; + } + +} + prefix_ senf::log::FileTarget::FileTarget(std::string const & file) - : ofstream_t(file.c_str(), std::ofstream::app), IOStreamTarget(file, ofstream_t::member), + : ofstream_t(file.c_str(), std::ofstream::app), + IOStreamTarget(quoteFilename(file), ofstream_t::member), file_(file) { consoleDir().add( "reopen", senf::membind( diff --git a/Utils/Logger/SyslogTarget.cc b/Utils/Logger/SyslogTarget.cc index 7c85321..40cdd58 100644 --- a/Utils/Logger/SyslogTarget.cc +++ b/Utils/Logger/SyslogTarget.cc @@ -68,10 +68,13 @@ prefix_ senf::log::SyslogTarget::RegisterConsole::RegisterConsole() .doc("Create new syslog target."); } -prefix_ void senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility) +prefix_ boost::shared_ptr +senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr(new SyslogTarget(facility))); + std::auto_ptr tp (new SyslogTarget(facility)); + Target & target (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return target.consoleDir().node().thisptr(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/SyslogTarget.hh b/Utils/Logger/SyslogTarget.hh index 0049f59..eeebbb9 100644 --- a/Utils/Logger/SyslogTarget.hh +++ b/Utils/Logger/SyslogTarget.hh @@ -28,12 +28,16 @@ // Custom includes #include +#include #include "Target.hh" //#include "SyslogTarget.mpp" ///////////////////////////////hh.p//////////////////////////////////////// namespace senf { + + namespace console { class DirectoryNode; } + namespace log { /** \brief Log target writing to the syslog @@ -118,7 +122,8 @@ namespace log { private: struct RegisterConsole { RegisterConsole(); - static void create(LogFacility facility); + static boost::shared_ptr create( + LogFacility facility); static RegisterConsole instance; }; }; diff --git a/Utils/Logger/SyslogUDPTarget.cc b/Utils/Logger/SyslogUDPTarget.cc index af8da40..e420ec5 100644 --- a/Utils/Logger/SyslogUDPTarget.cc +++ b/Utils/Logger/SyslogUDPTarget.cc @@ -84,62 +84,74 @@ prefix_ senf::log::SyslogUDPTarget::RegisterConsole::RegisterConsole() namespace kw = senf::console::kw; detail::TargetRegistry::instance().consoleDir().add( - "udp-target", static_cast( + "udp-target", + static_cast( &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", + " 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( + "udp-target", + static_cast( &RegisterConsole::create)) .arg("address") .arg("facility", kw::default_value = USER); detail::TargetRegistry::instance().consoleDir().add( - "udp-target", static_cast( + "udp-target", + static_cast( &RegisterConsole::create)) .arg("address") .arg("facility", kw::default_value = USER); detail::TargetRegistry::instance().consoleDir().add( - "udp-target", static_cast( + "udp-target", + static_cast( &RegisterConsole::create)) .arg("address") .arg("facility", kw::default_value = USER); } -prefix_ void +prefix_ boost::shared_ptr senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4SocketAddress const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr(new SyslogUDPTarget(target, facility))); + std::auto_ptr tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } -prefix_ void +prefix_ boost::shared_ptr senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4Address const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr(new SyslogUDPTarget(target, facility))); + std::auto_ptr tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } -prefix_ void +prefix_ boost::shared_ptr senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6SocketAddress const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr(new SyslogUDPTarget(target, facility))); + std::auto_ptr tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } -prefix_ void +prefix_ boost::shared_ptr senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6Address const & target, LogFacility facility) { - detail::TargetRegistry::instance().dynamicTarget( - std::auto_ptr(new SyslogUDPTarget(target, facility))); + std::auto_ptr tp (new SyslogUDPTarget(target, facility)); + Target & tg (*tp.get()); + detail::TargetRegistry::instance().dynamicTarget(tp); + return tg.consoleDir().node().thisptr(); } ///////////////////////////////cc.e//////////////////////////////////////// diff --git a/Utils/Logger/SyslogUDPTarget.hh b/Utils/Logger/SyslogUDPTarget.hh index e6f35ff..b940153 100644 --- a/Utils/Logger/SyslogUDPTarget.hh +++ b/Utils/Logger/SyslogUDPTarget.hh @@ -154,14 +154,14 @@ namespace log { 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 boost::shared_ptr create( + senf::INet4SocketAddress const & target, LogFacility facility = USER); + static boost::shared_ptr create( + senf::INet4Address const & target, LogFacility facility = USER); + static boost::shared_ptr create( + senf::INet6SocketAddress const & target, LogFacility facility = USER); + static boost::shared_ptr create( + senf::INet6Address const & target, LogFacility facility = USER); static RegisterConsole instance; }; };