/**< 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
parseLoop(commands.begin(), commands.end(), "<unknown>", 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"
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) {} };
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
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;
;
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_) ]
;
| ch_p(';') [ token_ = construct_<Token>(
Token::CommandTerminator,
";") ]
- | punctuation_p [ token_ = construct_<Token>(
+ | self.punctuation_p [ token_ = construct_<Token>(
Token::OtherPunctuation,
construct_<std::string>(1u, arg1)) ]
;
word // Returns value in context.token
= lexeme_d
[
- (+ word_p) [ str_ = construct_<std::string>(arg1, arg2) ]
+ (+ self.word_p) [ str_ = construct_<std::string>(arg1, arg2) ]
]
>> eps_p [ token_ = construct_<Token>(
Token::Word,
;
skip
- = space_p | comment_p('#')
+ = self.space_p | comment_p('#')
;
///////////////////////////////////////////////////////////////////
};
};
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::special_p (
+ "/(){};\"");
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::punctuation_p (
+ ",=");
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::space_p (
+ " \t\n\r");
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::invalid_p (
+ (boost::spirit::chset<>('\0') | boost::spirit::chset<>("\x01-\x20")) - space_p );
+ template <class PD> boost::spirit::chset<> CommandGrammar<PD>::word_p (
+ boost::spirit::anychar_p - special_p - punctuation_p - space_p - invalid_p);
+ template <class PD> boost::spirit::distinct_parser<> CommandGrammar<PD>::keyword_p (
+ word_p | boost::spirit::ch_p('/'));
+
#endif
}}}
#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(
.doc("Create new syslog target.");
}
-prefix_ void senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility)
+prefix_ boost::shared_ptr<senf::console::DirectoryNode>
+senf::log::SyslogTarget::RegisterConsole::create(LogFacility facility)
{
- detail::TargetRegistry::instance().dynamicTarget(
- std::auto_ptr<Target>(new SyslogTarget(facility)));
+ std::auto_ptr<Target> tp (new SyslogTarget(facility));
+ Target & target (*tp.get());
+ detail::TargetRegistry::instance().dynamicTarget(tp);
+ return target.consoleDir().node().thisptr();
}
///////////////////////////////cc.e////////////////////////////////////////
// Custom includes
#include <syslog.h>
+#include <boost/shared_ptr.hpp>
#include "Target.hh"
//#include "SyslogTarget.mpp"
///////////////////////////////hh.p////////////////////////////////////////
namespace senf {
+
+ namespace console { class DirectoryNode; }
+
namespace log {
/** \brief Log target writing to the syslog
private:
struct RegisterConsole {
RegisterConsole();
- static void create(LogFacility facility);
+ static boost::shared_ptr<senf::console::DirectoryNode> create(
+ LogFacility facility);
static RegisterConsole instance;
};
};
namespace kw = senf::console::kw;
detail::TargetRegistry::instance().consoleDir().add(
- "udp-target", static_cast<void (*)(INet4SocketAddress const &, LogFacility)>(
+ "udp-target",
+ static_cast<senf::console::DirectoryNode::ptr (*)(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",
+ " 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)>(
+ "udp-target",
+ static_cast<senf::console::DirectoryNode::ptr (*)(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)>(
+ "udp-target",
+ static_cast<senf::console::DirectoryNode::ptr (*)(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)>(
+ "udp-target",
+ static_cast<senf::console::DirectoryNode::ptr (*)(INet6Address const &, LogFacility)>(
&RegisterConsole::create))
.arg("address")
.arg("facility", kw::default_value = USER);
}
-prefix_ void
+prefix_ boost::shared_ptr<senf::console::DirectoryNode>
senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4SocketAddress const & target,
LogFacility facility)
{
- detail::TargetRegistry::instance().dynamicTarget(
- std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+ std::auto_ptr<Target> 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::console::DirectoryNode>
senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet4Address const & target,
LogFacility facility)
{
- detail::TargetRegistry::instance().dynamicTarget(
- std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+ std::auto_ptr<Target> 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::console::DirectoryNode>
senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6SocketAddress const & target,
LogFacility facility)
{
- detail::TargetRegistry::instance().dynamicTarget(
- std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+ std::auto_ptr<Target> 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::console::DirectoryNode>
senf::log::SyslogUDPTarget::RegisterConsole::create(senf::INet6Address const & target,
LogFacility facility)
{
- detail::TargetRegistry::instance().dynamicTarget(
- std::auto_ptr<Target>(new SyslogUDPTarget(target, facility)));
+ std::auto_ptr<Target> tp (new SyslogUDPTarget(target, facility));
+ Target & tg (*tp.get());
+ detail::TargetRegistry::instance().dynamicTarget(tp);
+ return tg.consoleDir().node().thisptr();
}
///////////////////////////////cc.e////////////////////////////////////////
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<senf::console::DirectoryNode> create(
+ senf::INet4SocketAddress const & target, LogFacility facility = USER);
+ static boost::shared_ptr<senf::console::DirectoryNode> create(
+ senf::INet4Address const & target, LogFacility facility = USER);
+ static boost::shared_ptr<senf::console::DirectoryNode> create(
+ senf::INet6SocketAddress const & target, LogFacility facility = USER);
+ static boost::shared_ptr<senf::console::DirectoryNode> create(
+ senf::INet6Address const & target, LogFacility facility = USER);
static RegisterConsole instance;
};
};