From: g0dil Date: Fri, 30 May 2008 08:17:13 +0000 (+0000) Subject: Utils: Add some spirit/phoenix helpers X-Git-Url: http://g0dil.de/git?a=commitdiff_plain;h=42f556b7d7c8f210c5919fcb298b0dccdae568e3;p=senf.git Utils: Add some spirit/phoenix helpers Console: Rewrite parser semantic actions to use phoenix (much (cd ..) simpler ...) git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@861 270642c3-0616-0410-b53a-bc976706d245 --- diff --git a/Console/Parse.ih b/Console/Parse.ih index 56628c9..dbdf89e 100644 --- a/Console/Parse.ih +++ b/Console/Parse.ih @@ -28,15 +28,11 @@ // Custom includes #include -#include #include #include -#include #include #include -#include -#include -#include +#include "../Utils/Phoenix.hh" ///////////////////////////////ih.p//////////////////////////////////////// @@ -47,30 +43,6 @@ namespace detail { #ifndef DOXYGEN /////////////////////////////////////////////////////////////////////////// - // append_a - - struct append_action - { - template - void act(T & ref, Value const & value) const - { ref += T(1, value); } - - template - void act(T & ref, Iterator const & f, Iterator const & l) const - { ref += T(f,l); } - }; - - template - inline boost::spirit::ref_value_actor - append_a(T & ref) - { return boost::spirit::ref_value_actor(ref); } - - template - inline boost::spirit::ref_const_ref_actor - append_a(T & ref, Value const & value) - { return boost::spirit::ref_const_ref_actor(ref, value); } - - /////////////////////////////////////////////////////////////////////////// // Grammar template @@ -91,11 +63,6 @@ namespace detail { std::vector path; char ch; Token token; - - // OUCH ... This is sooooo stupid .. push_back_a and assign_a take their - // arguments by const-reference and STORE the REFERENCE ... they do NOT accept - // literal values !!!!!! - static const Token EmptyToken; }; Context & context; @@ -110,69 +77,6 @@ namespace detail { ParseDispatcher & dispatcher; - struct Dispatch_actor - { - Dispatch_actor(boost::function fn_) : fn (fn_) {} - - template - void operator()(Value const & value) const - { fn(); } - - template - void operator()(Iterator const & f, Iterator const & l) const - { fn(); } - - boost::function fn; - }; - - template - Dispatch_actor dispatch(Callback cb) const - { return Dispatch_actor(boost::bind(cb, boost::ref(dispatcher))); } - - template - Dispatch_actor dispatch(Callback cb, Arg const & arg) const - { return Dispatch_actor(boost::bind(cb, boost::ref(dispatcher), arg)); } - - template - Dispatch_actor dispatch(Callback cb, Arg1 const & arg1, Arg2 const & arg2) const - { return Dispatch_actor(boost::bind(cb, boost::ref(dispatcher), arg1, arg2)); } - - struct TokenSetter_actor - { - TokenSetter_actor(Context & c, TokenType t) : c_ (c), t_ (t) {} - - void operator()(std::string const & value) const - { c_.token = Token(t_, value); } - void operator()(char value) const - { c_.token = Token(t_, std::string(1,value)); } - template void operator()(Iterator const & f, Iterator const & l) const - { c_.token = Token(t_, std::string(f,l)); } - - Context & c_; - TokenType t_; - }; - - struct TokenSetter_value_actor - : public TokenSetter_actor - { - TokenSetter_value_actor(Context & c, TokenType t, std::string & v) - : TokenSetter_actor(c,t), v_ (v) {} - - template void operator()(Value const &) const - { TokenSetter_actor::operator()(v_); } - - template void operator()(Iterator const &, Iterator const &) const - { TokenSetter_actor::operator()(v_); } - - std::string & v_; - }; - - TokenSetter_actor set_token_a(TokenType t) const - { return TokenSetter_actor(context, t); } - - TokenSetter_value_actor set_token_a(TokenType t, std::string & arg) const - { return TokenSetter_value_actor(context, t, arg); } - /////////////////////////////////////////////////////////////////////////// CommandGrammar(ParseDispatcher & d, Context & c) @@ -217,9 +121,15 @@ namespace detail { { using namespace boost::spirit; - using namespace phoenix; + using namespace ::phoenix; + using namespace senf::phoenix; typedef ParseDispatcher PD; - typedef Token AT; + + actor< variable< char > > ch_ (self.context.ch); + actor< variable< std::string > > str_ (self.context.str); + actor< variable< std::vector > > path_ (self.context.path); + actor< variable< Token > > token_ (self.context.token); + actor< variable< ParseDispatcher > > d_ (self.dispatcher); /////////////////////////////////////////////////////////////////// // Spirit grammar @@ -269,34 +179,29 @@ namespace detail { builtin = keyword_p("cd") >> path - >> eps_p [ self.dispatch(&PD::builtin_cd, - boost::ref(self.context.path)) ] + >> eps_p [ bind(&PD::builtin_cd)(d_, path_) ] | keyword_p("ls") >> ! path - >> eps_p [ self.dispatch(&PD::builtin_ls, - boost::ref(self.context.path)) ] - | keyword_p("exit") [ self.dispatch(&PD::builtin_exit) ] + >> eps_p [ bind(&PD::builtin_ls)(d_, path_) ] + | keyword_p("exit") [ bind(&PD::builtin_exit)(d_) ] | keyword_p("help") >> ! path - >> eps_p [ self.dispatch(&PD::builtin_help, - boost::ref(self.context.path)) ] + >> eps_p [ bind(&PD::builtin_help)(d_, path_) ] ; group_start - = ch_p('{') [ self.dispatch(&PD::pushDirectory, - boost::ref(self.context.path)) ] + = ch_p('{') [ bind(&PD::pushDirectory)(d_, path_) ] ; group_close - = ch_p('}') [ self.dispatch(&PD::popDirectory) ] + = ch_p('}') [ bind(&PD::popDirectory)(d_) ] ; statement - = eps_p [ self.dispatch(&PD::beginCommand, - boost::ref(self.context.path)) ] + = eps_p [ bind(&PD::beginCommand)(d_, path_) ] >> arguments - >> statement_end [ self.dispatch(&PD::endCommand) ] + >> statement_end [ bind(&PD::endCommand)(d_) ] ; arguments @@ -304,8 +209,7 @@ namespace detail { ; argument - = simple_argument [ self.dispatch(&PD::pushToken, - boost::ref(self.context.token)) ] + = simple_argument [ bind(&PD::pushToken)(d_, token_) ] | balanced_tokens ; @@ -316,85 +220,92 @@ namespace detail { ; string // Returns value in context.token - = eps_p [ clear_a(self.context.str) ] + = eps_p [ clear(str_) ] >> lexeme_d [ ch_p('"') - >> * ( ( lex_escape_ch_p[ assign_a(self.context.ch) ] + >> * ( ( lex_escape_ch_p[ ch_ = arg1 ] - '"' - ) [ append_a(self.context.str, - self.context.ch) ] + ) [ str_ += ch_ ] ) - >> ch_p('"') [ self.set_token_a(AT::BasicString, - self.context.str) ] + >> ch_p('"') [ token_ = construct_(Token::BasicString, + str_) ] ] ; hexstring // Returns value in context.token - = eps_p [ clear_a(self.context.str) ] + = eps_p [ clear(str_) ] >> confix_p( "x\"", * hexbyte, '"' ) - [ self.set_token_a(AT::HexString, - self.context.str) ] + [ token_ = construct_(Token::HexString, + str_) ] ; path // Returns value in context.path - = eps_p [ clear_a(self.context.path) ] + = eps_p [ clear(path_) ] >> relpath | abspath ; relpath - = ( word [ push_back_a(self.context.path, - self.context.token) ] + = ( word [ push_back(path_, token_) ] % ch_p('/') ) - >> ( ! ch_p('/') [ push_back_a(self.context.path, - self.context.EmptyToken) ] ) + >> ( ! ch_p('/') [ push_back(path_, construct_()) ] ) ; abspath - = ch_p('/') [ push_back_a(self.context.path, - self.context.EmptyToken) ] + = ch_p('/') [ push_back(path_, construct_()) ] >> ( relpath - | eps_p [ push_back_a(self.context.path, - self.context.EmptyToken) ] ) + | eps_p [ push_back(path_, construct_()) ] ) ; balanced_tokens - = ch_p('(') [ self.set_token_a(AT::ArgumentGroupOpen) ] - [ self.dispatch(&PD::pushToken, - boost::ref(self.context.token)) ] + = ch_p('(') [ token_ = construct_( + Token::ArgumentGroupOpen, + "(") ] + [ bind(&PD::pushToken)(d_, token_) ] >> * token - >> ch_p(')') [ self.set_token_a(AT::ArgumentGroupClose) ] - [ self.dispatch(&PD::pushToken, - boost::ref(self.context.token)) ] + >> ch_p(')') [ token_ = construct_( + Token::ArgumentGroupClose, + ")") ] + [ bind(&PD::pushToken)(d_, token_) ] ; token - = simple_argument [ self.dispatch(&PD::pushToken, - boost::ref(self.context.token)) ] - | punctuation [ self.dispatch(&PD::pushToken, - boost::ref(self.context.token)) ] + = simple_argument [ bind(&PD::pushToken)(d_, token_) ] + | punctuation [ bind(&PD::pushToken)(d_, token_) ] | balanced_tokens ; punctuation // Returns value in context.str - = ch_p('/') [ self.set_token_a(AT::PathSeparator) ] - | ch_p('{') [ self.set_token_a(AT::DirectoryGroupOpen) ] - | ch_p('}') [ self.set_token_a(AT::DirectoryGroupClose) ] - | ch_p(';') [ self.set_token_a(AT::CommandTerminator) ] - | punctuation_p [ self.set_token_a(AT::OtherPunctuation) ] + = ch_p('/') [ token_ = construct_( + Token::PathSeparator, + "/") ] + | ch_p('{') [ token_ = construct_( + Token::DirectoryGroupOpen, + "{") ] + | ch_p('}') [ token_ = construct_( + Token::DirectoryGroupClose, + "}") ] + | ch_p(';') [ token_ = construct_( + Token::CommandTerminator, + ";") ] + | punctuation_p [ token_ = construct_( + Token::OtherPunctuation, + construct_(1u, arg1)) ] ; word // Returns value in context.token = lexeme_d [ - (+ word_p) [ assign_a(self.context.str) ] + (+ word_p) [ str_ = construct_(arg1, arg2) ] ] - >> eps_p [ self.set_token_a(AT::Word, self.context.str) ] + >> eps_p [ token_ = construct_( + Token::Word, + str_) ] ; hexbyte = uint_parser() - [ append_a(self.context.str) ] + [ push_back(str_, arg1) ] ; statement_end @@ -441,9 +352,6 @@ namespace detail { }; }; - template - Token const CommandGrammar::Context::EmptyToken; - #endif }}} diff --git a/Console/Readline.cc b/Console/Readline.cc index dc8bd6a..094c8e4 100644 --- a/Console/Readline.cc +++ b/Console/Readline.cc @@ -150,6 +150,7 @@ prefix_ senf::console::detail::ReadlineClientReader::ReadlineClientReader(Client 0xFF, 0xFB, 0x03, // IAC WILL SGA 0x00 }; handle().write(options, options+sizeof(options)); + handle().write(std::string("(readline support enabled)\r\n")); strncpy(promptBuffer_, promptString().c_str(), 1024); promptBuffer_[1023] = 0; diff --git a/Console/Server.cc b/Console/Server.cc index 310e341..248e07b 100644 --- a/Console/Server.cc +++ b/Console/Server.cc @@ -254,7 +254,6 @@ prefix_ senf::console::Client::Client(Server & server, ClientHandle handle) prefix_ void senf::console::Client::setInteractive() { - SENF_LOG(("Set client interactive")); binding_.disable(); timer_.disable(); mode_ = Server::Interactive; @@ -264,7 +263,6 @@ prefix_ void senf::console::Client::setInteractive() prefix_ void senf::console::Client::setNoninteractive() { - SENF_LOG(("Set client non-interactive")); binding_.disable(); timer_.disable(); mode_ = Server::Noninteractive; @@ -279,8 +277,6 @@ prefix_ void senf::console::Client::translate(std::string & data) prefix_ std::string::size_type senf::console::Client::handleInput(std::string data, bool incremental) { - SENF_LOG(("Data: " << data)); - if (data.empty() && ! incremental) data = lastCommand_; else diff --git a/Utils/Phoenix.hh b/Utils/Phoenix.hh new file mode 100644 index 0000000..c0e81e5 --- /dev/null +++ b/Utils/Phoenix.hh @@ -0,0 +1,59 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. + +/** \file + \brief Phoenix public header */ + +#ifndef HH_Phoenix_ +#define HH_Phoenix_ 1 + +// Custom includes +#include + +//#include "Phoenix.mpp" +#include "Phoenix.ih" +///////////////////////////////hh.p//////////////////////////////////////// + +namespace senf { +namespace phoenix { + + ::phoenix::function const push_back; + ::phoenix::function const clear; + +}} + +///////////////////////////////hh.e//////////////////////////////////////// +//#include "Phoenix.cci" +//#include "Phoenix.ct" +//#include "Phoenix.cti" +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: diff --git a/Utils/Phoenix.ih b/Utils/Phoenix.ih new file mode 100644 index 0000000..485bbc4 --- /dev/null +++ b/Utils/Phoenix.ih @@ -0,0 +1,69 @@ +// $Id$ +// +// Copyright (C) 2008 +// Fraunhofer Institute for Open Communication Systems (FOKUS) +// Competence Center NETwork research (NET), St. Augustin, GERMANY +// Stefan Bund +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 2 of the License, or +// (at your option) any later version. +// +// This program 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. + +/** \file + \brief Phoenix internal header */ + +#ifndef IH_Phoenix_ +#define IH_Phoenix_ 1 + +// Custom includes + +///////////////////////////////ih.p//////////////////////////////////////// + +namespace senf { +namespace phoenix { +namespace detail { + + struct push_back { + template + struct result { typedef void type; }; + + template + void operator()(A1 & a1, A2 a2) const + { a1.push_back(a2); } + }; + + struct clear { + template + struct result { typedef void type; }; + + template + void operator()(A1 & a1) const + { a1.clear(); } + }; + +}}} + +///////////////////////////////ih.e//////////////////////////////////////// +#endif + + +// Local Variables: +// mode: c++ +// fill-column: 100 +// comment-column: 40 +// c-file-style: "senf" +// indent-tabs-mode: nil +// ispell-local-dictionary: "american" +// compile-command: "scons -u test" +// End: