X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=Console%2FParse.cc;h=a631f0f1ca4618a6bacc5d6b3c49b68e91744928;hb=c0b5c560da72983939b286632ac481e076649ddb;hp=502dd1cd4c34dcff5a84f6128ac6f182163718db;hpb=327ff174bdc67db20c64d92c9a171abfa5443333;p=senf.git diff --git a/Console/Parse.cc b/Console/Parse.cc index 502dd1c..a631f0f 100644 --- a/Console/Parse.cc +++ b/Console/Parse.cc @@ -27,7 +27,11 @@ #include "Parse.ih" // Custom includes +#include #include +#include +#include "../Utils/String.hh" +#include "../Utils/Exception.hh" //#include "Parse.mpp" #define prefix_ @@ -42,7 +46,10 @@ namespace detail { static void init(ParseCommandInfo & info) { info.init(); } - static void setCommand(ParseCommandInfo & info, std::string const & commandPath) + static void setBuiltin(ParseCommandInfo & info, ParseCommandInfo::BuiltinCommand builtin) + { info.setBuiltin(builtin); } + + static void setCommand(ParseCommandInfo & info, std::vector & commandPath) { info.setCommand(commandPath); } static void startArgument(ParseCommandInfo & info) @@ -63,48 +70,77 @@ namespace detail { struct ParseDispatcher { - ParseDispatcher() - : info_ (0) {} - - ParseCommandInfo * info_; - - ParseCommandInfo & info() { - SENF_ASSERT( info_ ); - return *info_; - } + ParseCommandInfo info_; + CommandParser::Callback cb_; struct BindInfo { - BindInfo( ParseDispatcher & d, ParseCommandInfo & i) - : dispatcher (d) { dispatcher.info_ = &i; } - - ~BindInfo() { dispatcher.info_ = 0; } + BindInfo( ParseDispatcher & d, CommandParser::Callback cb) + : dispatcher (d) { dispatcher.cb_ = cb; } + ~BindInfo() { dispatcher.cb_ = 0; } ParseDispatcher & dispatcher; }; - void beginCommand(std::string const & command) - { ParserAccess::init(info()); - ParserAccess::setCommand(info(), command); } + void beginCommand(std::vector & command) + { ParserAccess::init(info_); + ParserAccess::setCommand(info_, command); } void endCommand() - { ParserAccess::finalize(info()); } + { ParserAccess::finalize(info_); cb_(info_); } void pushArgument(std::string const & argument) - { ParserAccess::startArgument(info()); - ParserAccess::addToken(info(), ParserAccess::makeToken(argument)); - ParserAccess::endArgument(info()); } + { ParserAccess::startArgument(info_); + ParserAccess::addToken(info_, ParserAccess::makeToken(argument)); + ParserAccess::endArgument(info_); } void openGroup() - { ParserAccess::startArgument(info()); } + { ParserAccess::startArgument(info_); } void closeGroup() - { ParserAccess::endArgument(info()); } + { ParserAccess::endArgument(info_); } void pushPunctuation(std::string const & token) - { ParserAccess::addToken(info(), ParserAccess::makeToken(token)); } + { ParserAccess::addToken(info_, ParserAccess::makeToken(token)); } void pushWord(std::string const & token) - { ParserAccess::addToken(info(), ParserAccess::makeToken(token)); } + { ParserAccess::addToken(info_, ParserAccess::makeToken(token)); } + + void builtin_cd(std::vector & path) + { ParserAccess::init(info_); + ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinCD); + setBuiltinPathArg(path); + ParserAccess::finalize(info_); cb_(info_); } + + void builtin_ls(std::vector & path) + { ParserAccess::init(info_); + ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinLS); + setBuiltinPathArg(path); + ParserAccess::finalize(info_); cb_(info_); } + + void pushDirectory(std::vector & path) + { ParserAccess::init(info_); + ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinPUSHD); + setBuiltinPathArg(path); + ParserAccess::finalize(info_); cb_(info_); } + + void popDirectory() + { ParserAccess::init(info_); + ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinPOPD); + ParserAccess::finalize(info_); cb_(info_); } + + void builtin_exit() + { ParserAccess::init(info_); + ParserAccess::setBuiltin(info_, ParseCommandInfo::BuiltinEXIT); + ParserAccess::finalize(info_); cb_(info_); } + + void setBuiltinPathArg(std::vector & path) + { + ParserAccess::startArgument(info_); + for (std::vector::const_iterator i (path.begin()); + i != path.end(); ++i) + ParserAccess::addToken(info_, ParserAccess::makeToken(*i)); + ParserAccess::endArgument(info_); + } }; }}} @@ -114,13 +150,13 @@ namespace detail { struct senf::console::ParseCommandInfo::MakeRange { + typedef ParseCommandInfo::argument_value_type result_type; + MakeRange() {} MakeRange(ParseCommandInfo::token_iterator b) : b_ (b) {} - + senf::console::ParseCommandInfo::token_iterator b_; - - typedef ParseCommandInfo::argument_value_type result_type; - + result_type operator()(TempArguments::iterator::value_type const & v) const { return result_type( b_ + v.first, b_ + v.second ); } @@ -139,31 +175,74 @@ prefix_ void senf::console::ParseCommandInfo::finalize() tempArguments_.clear(); } +prefix_ std::ostream & senf::console::operator<<(std::ostream & stream, + ParseCommandInfo const & info) +{ + if (info.builtin() == ParseCommandInfo::NoBuiltin) + stream << senf::stringJoin(info.commandPath(), "/"); + else { + char const * builtins[] = { "", "cd", "ls", "pushd", "popd", "exit" }; + stream << "builtin-" << builtins[info.builtin()]; + } + + ParseCommandInfo::ArgumentsRange args (info.arguments()); + for (ParseCommandInfo::argument_iterator i (args.begin()); i != args.end(); ++i) { + ParseCommandInfo::token_iterator j (i->begin()); + stream << " ["; + if ( j != i->end() ) { + for (;;) { + stream << "'" << j->value() << "'"; + if ( ++j != i->end() ) stream << ' '; + else break; + } + } + stream << "]"; + } + + return stream; +} + /////////////////////////////////////////////////////////////////////////// -// senf::console::SingleCommandParser +// senf::console::CommandParser -struct senf::console::SingleCommandParser::Impl +struct senf::console::CommandParser::Impl { + typedef detail::CommandGrammar Grammar; + detail::ParseDispatcher dispatcher; - detail::CommandGrammar::Context context; - detail::CommandGrammar grammar; - detail::SkipGrammar skipGrammar; + Grammar::Context context; + Grammar grammar; Impl() : dispatcher(), context(), grammar(dispatcher, context) {} }; -prefix_ senf::console::SingleCommandParser::SingleCommandParser() +prefix_ senf::console::CommandParser::CommandParser() : impl_ (new Impl()) {} -prefix_ senf::console::SingleCommandParser::~SingleCommandParser() +prefix_ senf::console::CommandParser::~CommandParser() {} -prefix_ bool senf::console::SingleCommandParser::parseCommand(std::string command, - ParseCommandInfo & info) +prefix_ bool senf::console::CommandParser::parse(std::string command, Callback cb) +{ + detail::ParseDispatcher::BindInfo bind (impl().dispatcher, cb); + return boost::spirit::parse( command.begin(), command.end(), + impl().grammar.use_parser(), + impl().grammar.use_parser() + ).full; +} + +prefix_ bool senf::console::CommandParser::parseFile(std::string filename, Callback cb) { - detail::ParseDispatcher::BindInfo bind (impl().dispatcher, info); - return boost::spirit::parse( command.c_str(), impl().grammar, impl().skipGrammar ).full; + detail::ParseDispatcher::BindInfo bind (impl().dispatcher, cb); + boost::spirit::file_iterator<> i (filename); + if (!i) throw SystemException(ENOENT SENF_EXC_DEBUGINFO); + boost::spirit::file_iterator<> const i_end (i.make_end()); + + return boost::spirit::parse( i, i_end, + impl().grammar.use_parser(), + impl().grammar.use_parser() + ).full; } ///////////////////////////////cc.e////////////////////////////////////////