X-Git-Url: http://g0dil.de/git?a=blobdiff_plain;f=senf%2FUtils%2FConsole%2FParse.cc;h=afae4feaaa5b20f9e189853c49532ff66f7f5f77;hb=6aae6e526573187ece558842e928578e5aa4cc4c;hp=87235100f46e91ae1ad0b216b5231deaf5344363;hpb=601d1f509f5bb24df167a4dd5a20da67a0af9af8;p=senf.git diff --git a/senf/Utils/Console/Parse.cc b/senf/Utils/Console/Parse.cc index 8723510..afae4fe 100644 --- a/senf/Utils/Console/Parse.cc +++ b/senf/Utils/Console/Parse.cc @@ -1,6 +1,6 @@ // $Id$ // -// Copyright (C) 2008 +// Copyright (C) 2008 // Fraunhofer Institute for Open Communication Systems (FOKUS) // Competence Center NETwork research (NET), St. Augustin, GERMANY // Stefan Bund @@ -28,11 +28,20 @@ // Custom includes #include +#include #include -#include -#include -#include "../../Utils/Exception.hh" -#include "../../Utils/senfassert.hh" +#include + +#if HAVE_BOOST_SPIRIT_INCLUDE_CLASSIC_HPP +# include +# include +#else +# include +# include +#endif + +#include +#include //#include "Parse.mpp" #define prefix_ @@ -94,7 +103,7 @@ namespace detail { void popDirectory() { info_->clear(); info_->builtin(ParseCommandInfo::BuiltinPOPD); } - + void builtin_exit() { info_->clear(); info_->builtin(ParseCommandInfo::BuiltinEXIT); } @@ -144,15 +153,15 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & os, Token const "Word" }; // The real table is: // static const int bitPosition[32] = { - // 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + // 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, // 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 }; // However, we have replaced all values >= sizeof(tokenTypeName) with 0 // and have added 1 to all the remaining values static const int bitPosition[32] = { - 1, 2, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 9, + 1, 2, 0, 3, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 5, 9, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 7, 0, 6, 0, 10 }; // We need to check token.type() against 0 explicitly since 0 and 1 will both be mapped to 0 - os << tokenTypeName[ token.type() + os << tokenTypeName[ token.type() ? bitPosition[(((token.type() & -token.type()) * 0x077CB531UL) >> 27) & 31] : 0 ] << "('" @@ -182,7 +191,7 @@ prefix_ std::ostream & senf::console::operator<<(std::ostream & stream, char const * builtins[] = { 0, "cd", "ls", "lr", "pushd", "popd", "exit", "help" }; 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()); @@ -261,9 +270,9 @@ struct senf::console::CommandParser::Impl #endif namespace { - + template - void throwParserError(Error const & err) + void throwParserError(Error const & err) { static char const * msg [] = { "end of statement expected", "path expected", @@ -276,8 +285,11 @@ namespace { } -namespace boost { +namespace boost { namespace spirit { +#if HAVE_BOOST_SPIRIT_INCLUDE_CLASSIC_HPP +namespace classic { +#endif template <> struct position_policy @@ -304,6 +316,9 @@ namespace spirit { } }; +#if HAVE_BOOST_SPIRIT_INCLUDE_CLASSIC_HPP +} +#endif }} prefix_ senf::console::CommandParser::CommandParser() @@ -317,38 +332,38 @@ prefix_ senf::console::CommandParser::~CommandParser() // we would need to expose the Impl member to the public, which we don't want to do. template -prefix_ Iterator senf::console::CommandParser::parseLoop(Iterator npb, Iterator npe, +prefix_ Iterator senf::console::CommandParser::parseLoop(Iterator npb, Iterator npe, std::string const & source, Callback cb) { - typedef boost::spirit::position_iterator< + typedef detail::boost_spirit::position_iterator< Iterator, detail::FilePositionWithIndex> PositionIterator; PositionIterator b (npb, npe, source); PositionIterator e (npe, npe, source); ParseCommandInfo info; detail::ParseDispatcher::BindInfo bind (impl().dispatcher, info); - boost::spirit::parse_info result; + detail::boost_spirit::parse_info result; for(;;) { - result = boost::spirit::parse( + result = detail::boost_spirit::parse( b, e, * impl().grammar.use_parser()); b = result.stop; - if (b == e) + if (b == e) return e.base(); info.clear(); try { - result = boost::spirit::parse(b, e, + result = detail::boost_spirit::parse(b, e, impl().grammar.use_parser(), impl().grammar.use_parser()); } - catch (boost::spirit::parser_error & ex) { + catch (detail::boost_spirit::parser_error & ex) { if (impl().grammar.incremental && ex.where == e) return b.base(); else throwParserError(ex); } // Otherwise the error handling in the parser is broken - SENF_ASSERT( result.hit ); - if (! info.empty()) + SENF_ASSERT( result.hit, "Internal parser failure (error handling broken?)" ); + if (! info.empty()) try { cb(info); } @@ -368,27 +383,40 @@ prefix_ void senf::console::CommandParser::parse(std::string const & command, Ca prefix_ void senf::console::CommandParser::parseFile(std::string const & filename, Callback 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()); + // file_iterator sets errno to EINVAL and returns error when file size is 0 + // so we check the file size before + struct stat statBuf; + if (stat( filename.c_str(), &statBuf) != 0) + throw SystemException(filename, errno SENF_EXC_DEBUGINFO); + if (statBuf.st_size == 0) return; + detail::boost_spirit::file_iterator<> i (filename); + if (!i) { + if (errno == 0) + // hmm.. errno==0 but the file_iterator is false; something is wrong but we + // do not know what exactly, so we throw a SystemeException with EINVAL + throw SystemException(filename, EINVAL SENF_EXC_DEBUGINFO); + else + throw SystemException(filename, errno SENF_EXC_DEBUGINFO); + } + detail::boost_spirit::file_iterator<> const i_end (i.make_end()); parseLoop(i, i_end, filename, cb); } prefix_ void senf::console::CommandParser::parseArguments(std::string const & arguments, ParseCommandInfo & info) { - typedef boost::spirit::position_iterator< + typedef detail::boost_spirit::position_iterator< std::string::const_iterator, detail::FilePositionWithIndex> PositionIterator; PositionIterator b (arguments.begin(), arguments.end(), std::string("")); PositionIterator e (arguments.end(), arguments.end(), std::string("")); detail::ParseDispatcher::BindInfo bind (impl().dispatcher, info); - boost::spirit::parse_info result; + detail::boost_spirit::parse_info result; try { - result = boost::spirit::parse( b, e, + result = detail::boost_spirit::parse( b, e, impl().grammar.use_parser(), impl().grammar.use_parser() ); } - catch (boost::spirit::parser_error & ex) { + catch (detail::boost_spirit::parser_error & ex) { throwParserError(ex); } if (! result.full) { @@ -401,18 +429,18 @@ prefix_ void senf::console::CommandParser::parseArguments(std::string const & ar prefix_ void senf::console::CommandParser::parsePath(std::string const & path, ParseCommandInfo & info) { - typedef boost::spirit::position_iterator< + typedef detail::boost_spirit::position_iterator< std::string::const_iterator, detail::FilePositionWithIndex> PositionIterator; PositionIterator b (path.begin(), path.end(), std::string("")); PositionIterator e (path.end(), path.end(), std::string("")); detail::ParseDispatcher::BindInfo bind (impl().dispatcher, info); - boost::spirit::parse_info result; + detail::boost_spirit::parse_info result; try { - result = boost::spirit::parse( b, e, + result = detail::boost_spirit::parse( b, e, impl().grammar.use_parser(), impl().grammar.use_parser() ); } - catch (boost::spirit::parser_error & ex) { + catch (detail::boost_spirit::parser_error & ex) { throwParserError(ex); } if (! result.full) { @@ -439,7 +467,7 @@ prefix_ std::string::size_type senf::console::CommandParser::parseIncremental(std::string const & commands, Callback cb) { SetIncremental si (*this); - return std::distance( commands.begin(), + return std::distance( commands.begin(), parseLoop(commands.begin(), commands.end(), "", cb) ); }