case ParseCommandInfo::BuiltinLS :
for (DirectoryNode::child_iterator i (cwd().children().begin());
- i != cwd().children().end(); ++i)
- output << i->first << "\n";
+ i != cwd().children().end(); ++i) {
+ output << i->first;
+ try {
+ (void) cwd()(i->first);
+ }
+ catch (std::bad_cast &) {
+ output << "/";
+ }
+ output << "\n";
+ }
break;
case ParseCommandInfo::BuiltinPUSHD :
prefix_ bool senf::console::Executor::chdir(ParseCommandInfo::argument_value_type const & path)
{
- try {
- DirectoryNode::ptr dir (cwd_.lock());
- ParseCommandInfo::token_iterator i (path.begin());
- ParseCommandInfo::token_iterator const i_end (path.end());
- if (i != i_end && i->value().empty()) {
- dir = boost::static_pointer_cast<DirectoryNode>(
+ if (path.size() == 1 && path.begin()->value() == "-") {
+ if (oldCwd_.expired()) {
+ oldCwd_ = cwd_;
+ cwd_ = boost::static_pointer_cast<DirectoryNode>(
root().shared_from_this());
- ++ i;
- }
- for (; i != i_end; ++i) {
- if (i->value() == "..") {
- dir = dir->parent();
- if (! dir)
+ } else
+ swap(cwd_, oldCwd_);
+ }
+ else {
+ try {
+ DirectoryNode::ptr dir (cwd_.lock());
+ ParseCommandInfo::token_iterator i (path.begin());
+ ParseCommandInfo::token_iterator const i_end (path.end());
+ if (i != i_end && i->value().empty()) {
+ dir = boost::static_pointer_cast<DirectoryNode>(
+ root().shared_from_this());
+ ++ i;
+ }
+ for (; i != i_end; ++i) {
+ if (i->value() == "..") {
+ dir = dir->parent();
+ if (! dir)
+ dir = boost::static_pointer_cast<DirectoryNode>(
+ root().shared_from_this());
+ }
+ else if (! i->value().empty() && i->value() != ".")
dir = boost::static_pointer_cast<DirectoryNode>(
- root().shared_from_this());
+ (*dir)[i->value()].shared_from_this());
}
- else if (! i->value().empty() && i->value() != ".")
- dir = boost::static_pointer_cast<DirectoryNode>(
- (*dir)[i->value()].shared_from_this());
+ oldCwd_ = cwd_;
+ cwd_ = dir;
+ }
+ catch (std::bad_cast &) {
+ return false;
+ }
+ catch (UnknownNodeNameException &) {
+ return false;
}
- cwd_ = dir;
- }
- catch (std::bad_cast &) {
- return false;
- }
- catch (UnknownNodeNameException &) {
- return false;
}
return true;
}
prefix_ senf::console::Executor::Executor()
{
- cwd_ = boost::static_pointer_cast<DirectoryNode>(
+ oldCwd_ = cwd_ = boost::static_pointer_cast<DirectoryNode>(
root().shared_from_this());
}
bool chdir(ParseCommandInfo::argument_value_type const & path);
DirectoryNode::weak_ptr cwd_;
+ DirectoryNode::weak_ptr oldCwd_;
typedef std::vector<DirectoryNode::weak_ptr> DirStack;
DirStack dirstack_;
};
#include "Parse.ih"
// Custom includes
-#include "../Utils/String.hh"
+#include <cerrno>
#include <boost/iterator/transform_iterator.hpp>
+#include <boost/spirit/iterator/file_iterator.hpp>
+#include "../Utils/String.hh"
+#include "../Utils/Exception.hh"
//#include "Parse.mpp"
#define prefix_
prefix_ bool senf::console::CommandParser::parse(std::string command, Callback cb)
{
detail::ParseDispatcher::BindInfo bind (impl().dispatcher, cb);
-# warning don't use c_str() in parse and add istream parser. Implement error checking in parser.
- return boost::spirit::parse( command.c_str(),
+ return boost::spirit::parse( command.begin(), command.end(),
+ impl().grammar.use_parser<Impl::Grammar::CommandParser>(),
+ impl().grammar.use_parser<Impl::Grammar::SkipParser>()
+ ).full;
+}
+
+prefix_ bool senf::console::CommandParser::parseFile(std::string filename, Callback cb)
+{
+ 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::CommandParser>(),
impl().grammar.use_parser<Impl::Grammar::SkipParser>()
).full;
///////////////////////////////////////////////////////////////////////////
bool parse(std::string command, Callback cb);
+ bool parseFile(std::string filename, Callback cb);
private:
struct Impl;
namespace boost { class singleton_pool {}; }
namespace boost { class totally_ordered {}; }
namespace boost { class true_type {}; }
+namespace boost { class enable_shared_from_this {}; }
+namespace boost { namespace spirit { class grammar {}; } }
+namespace boost { namespace spirit { class grammar_def {}; } }
namespace std { class exception {}; }
namespace std { class string {}; }
///\}