Console: Implement 'cd -'
g0dil [Sun, 23 Mar 2008 12:40:06 +0000 (12:40 +0000)]
Console: Add CommandParser::parseFile implementation
Console: Adourn 'ls' output with type information

git-svn-id: https://svn.berlios.de/svnroot/repos/senf/trunk@758 270642c3-0616-0410-b53a-bc976706d245

Console/Executor.cc
Console/Executor.cci
Console/Executor.hh
Console/Parse.cc
Console/Parse.hh
Utils/Externals.dox

index 71c3f78..43fc6d2 100644 (file)
@@ -56,8 +56,16 @@ prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & comman
 
     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 :
@@ -82,33 +90,44 @@ prefix_ bool senf::console::Executor::operator()(ParseCommandInfo const & comman
 
 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;
 }
index 6c20c2f..3126fa1 100644 (file)
@@ -35,7 +35,7 @@
 
 prefix_ senf::console::Executor::Executor()
 {
-    cwd_ = boost::static_pointer_cast<DirectoryNode>(
+    oldCwd_ = cwd_ = boost::static_pointer_cast<DirectoryNode>(
         root().shared_from_this());
 }
 
index be6f15f..bc3ce99 100644 (file)
@@ -71,6 +71,7 @@ namespace console {
         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_;
     };
index f143149..a631f0f 100644 (file)
 #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_
@@ -223,8 +226,20 @@ prefix_ senf::console::CommandParser::~CommandParser()
 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;
index 9d22ede..a4e452c 100644 (file)
@@ -146,6 +146,7 @@ namespace console {
         ///////////////////////////////////////////////////////////////////////////
 
         bool parse(std::string command, Callback cb);
+        bool parseFile(std::string filename, Callback cb);
 
     private:
         struct Impl;
index f517454..9d1dc8a 100644 (file)
@@ -11,6 +11,9 @@ namespace boost { class noncopyable {}; }
 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 {}; }
 ///\}