Просмотр исходного кода

Shell: Move the Shell to a separate directory and let's call it "Shell" :^)

Andreas Kling 6 лет назад
Родитель
Сommit
fe73543d41
7 измененных файлов с 217 добавлено и 180 удалено
  1. 2 2
      Applications/Terminal/main.cpp
  2. 2 0
      Kernel/sync.sh
  3. 3 0
      Shell/.gitignore
  4. 23 0
      Shell/Makefile
  5. 140 0
      Shell/Parser.cpp
  6. 46 0
      Shell/Parser.h
  7. 1 178
      Shell/main.cpp

+ 2 - 2
Applications/Terminal/main.cpp

@@ -65,9 +65,9 @@ static void make_shell(int ptm_fd)
             perror("ioctl(TIOCSCTTY)");
             exit(1);
         }
-        char* args[] = { "/bin/sh", nullptr };
+        char* args[] = { "/bin/Shell", nullptr };
         char* envs[] = { "TERM=xterm", "PATH=/bin:/usr/bin", nullptr };
-        rc = execve("/bin/sh", args, envs);
+        rc = execve("/bin/Shell", args, envs);
         if (rc < 0) {
             perror("execve");
             exit(1);

+ 2 - 0
Kernel/sync.sh

@@ -75,6 +75,8 @@ cp -v ../Games/Minesweeper/Minesweeper mnt/bin/Minesweeper
 ln -s Minesweeper mnt/bin/ms
 cp -v ../Games/Snake/Snake mnt/bin/Snake
 ln -s Snake mnt/bin/sn
+cp -v ../Shell/Shell mnt/bin/Shell
+ln -s Shell mnt/bin/sh
 cp -v kernel.map mnt/
 
 # Run local sync script, if it exists

+ 3 - 0
Shell/.gitignore

@@ -0,0 +1,3 @@
+*.o
+*.d
+Shell

+ 23 - 0
Shell/Makefile

@@ -0,0 +1,23 @@
+include ../Makefile.common
+
+OBJS = \
+    Parser.o \
+    main.o
+
+APP = Shell
+
+DEFINES += -DUSERLAND
+
+all: $(APP)
+
+$(APP): $(OBJS)
+	$(LD) -o $(APP) $(LDFLAGS) $(OBJS) -lcore -lc
+
+.cpp.o:
+	@echo "CXX $<"; $(CXX) $(CXXFLAGS) -o $@ -c $<
+
+-include $(OBJS:%.o=%.d)
+
+clean:
+	@echo "CLEAN"; rm -f $(APPS) $(OBJS) *.d
+

+ 140 - 0
Shell/Parser.cpp

@@ -0,0 +1,140 @@
+#include "Parser.h"
+#include <stdio.h>
+#include <unistd.h>
+
+void Parser::commit_token()
+{
+    if (m_token.is_empty())
+        return;
+    if (m_state == InRedirectionPath) {
+        m_redirections.last().path = String::copy(m_token);
+        m_token.clear_with_capacity();
+        return;
+    }
+    m_tokens.append(String::copy(m_token));
+    m_token.clear_with_capacity();
+};
+
+void Parser::commit_subcommand()
+{
+    if (m_tokens.is_empty())
+        return;
+    m_subcommands.append({ move(m_tokens), move(m_redirections) });
+}
+
+void Parser::do_pipe()
+{
+    m_redirections.append({ Redirection::Pipe, STDOUT_FILENO });
+    commit_subcommand();
+}
+
+void Parser::begin_redirect_read(int fd)
+{
+    m_redirections.append({ Redirection::FileRead, fd });
+}
+
+void Parser::begin_redirect_write(int fd)
+{
+    m_redirections.append({ Redirection::FileWrite, fd });
+}
+
+Vector<Subcommand> Parser::parse()
+{
+    for (int i = 0; i < m_input.length(); ++i) {
+        char ch = m_input.characters()[i];
+        switch (m_state) {
+        case State::Free:
+            if (ch == ' ') {
+                commit_token();
+                break;
+            }
+            if (ch == '|') {
+                commit_token();
+                if (m_tokens.is_empty()) {
+                    fprintf(stderr, "Syntax error: Nothing before pipe (|)\n");
+                    return { };
+                }
+                do_pipe();
+                break;
+            }
+            if (ch == '>') {
+                commit_token();
+                begin_redirect_write(STDOUT_FILENO);
+                m_state = State::InRedirectionPath;
+                break;
+            }
+            if (ch == '<') {
+                commit_token();
+                begin_redirect_read(STDIN_FILENO);
+                m_state = State::InRedirectionPath;
+                break;
+            }
+            if (ch == '\'') {
+                m_state = State::InSingleQuotes;
+                break;
+            }
+            if (ch == '\"') {
+                m_state = State::InDoubleQuotes;
+                break;
+            }
+            m_token.append(ch);
+            break;
+        case State::InRedirectionPath:
+            if (ch == '<') {
+                commit_token();
+                begin_redirect_read(STDIN_FILENO);
+                m_state = State::InRedirectionPath;
+                break;
+            }
+            if (ch == '>') {
+                commit_token();
+                begin_redirect_read(STDOUT_FILENO);
+                m_state = State::InRedirectionPath;
+                break;
+            }
+            if (ch == '|') {
+                commit_token();
+                if (m_tokens.is_empty()) {
+                    fprintf(stderr, "Syntax error: Nothing before pipe (|)\n");
+                    return { };
+                }
+                do_pipe();
+                m_state = State::Free;
+                break;
+            }
+            if (ch == ' ')
+                break;
+            m_token.append(ch);
+            break;
+        case State::InSingleQuotes:
+            if (ch == '\'') {
+                commit_token();
+                m_state = State::Free;
+                break;
+            }
+            m_token.append(ch);
+            break;
+        case State::InDoubleQuotes:
+            if (ch == '\"') {
+                commit_token();
+                m_state = State::Free;
+                break;
+            }
+            m_token.append(ch);
+            break;
+        };
+    }
+    commit_token();
+    commit_subcommand();
+
+    if (!m_subcommands.is_empty()) {
+        for (auto& redirection : m_subcommands.last().redirections) {
+            if (redirection.type == Redirection::Pipe) {
+                fprintf(stderr, "Syntax error: Nothing after last pipe (|)\n");
+                return { };
+            }
+        }
+    }
+
+    return move(m_subcommands);
+}

+ 46 - 0
Shell/Parser.h

@@ -0,0 +1,46 @@
+#pragma once
+
+#include <AK/AKString.h>
+#include <AK/Vector.h>
+
+struct Redirection {
+    enum Type { Pipe, FileWrite, FileRead, Rewire };
+    Type type;
+    int fd { -1 };
+    int rewire_fd { -1 };
+    String path { };
+};
+
+struct Subcommand {
+    Vector<String> args;
+    Vector<Redirection> redirections;
+};
+
+class Parser {
+public:
+    explicit Parser(const String& input) : m_input(input) { }
+
+    Vector<Subcommand> parse();
+
+private:
+    void commit_token();
+    void commit_subcommand();
+    void do_pipe();
+    void begin_redirect_read(int fd);
+    void begin_redirect_write(int fd);
+
+    enum State {
+        Free,
+        InSingleQuotes,
+        InDoubleQuotes,
+        InRedirectionPath,
+    };
+    State m_state { Free };
+    String m_input;
+
+    Vector<Subcommand> m_subcommands;
+    Vector<String> m_tokens;
+    Vector<Redirection> m_redirections;
+    Vector<char> m_token;
+};
+

+ 1 - 178
Userland/sh.cpp → Shell/main.cpp

@@ -13,6 +13,7 @@
 #include <sys/utsname.h>
 #include <AK/FileSystemPath.h>
 #include <LibCore/CElapsedTimer.h>
+#include "Parser.h"
 
 //#define SH_DEBUG
 
@@ -144,184 +145,6 @@ static bool handle_builtin(int argc, char** argv, int& retval)
     return false;
 }
 
-struct Redirection {
-    enum Type { Pipe, FileWrite, FileRead, Rewire };
-    Type type;
-    int fd { -1 };
-    int rewire_fd { -1 };
-    String path { };
-};
-
-struct Subcommand {
-    Vector<String> args;
-    Vector<Redirection> redirections;
-};
-
-class Parser {
-public:
-    explicit Parser(const String& input) : m_input(input) { }
-
-    Vector<Subcommand> parse();
-
-private:
-    void commit_token();
-    void commit_subcommand();
-    void do_pipe();
-    void begin_redirect_read(int fd);
-    void begin_redirect_write(int fd);
-
-    enum State {
-        Free,
-        InSingleQuotes,
-        InDoubleQuotes,
-        InRedirectionPath,
-    };
-    State m_state { Free };
-    String m_input;
-
-    Vector<Subcommand> m_subcommands;
-    Vector<String> m_tokens;
-    Vector<Redirection> m_redirections;
-    Vector<char> m_token;
-};
-
-void Parser::commit_token()
-{
-    if (m_token.is_empty())
-        return;
-    if (m_state == InRedirectionPath) {
-        m_redirections.last().path = String::copy(m_token);
-        m_token.clear_with_capacity();
-        return;
-    }
-    m_tokens.append(String::copy(m_token));
-    m_token.clear_with_capacity();
-};
-
-void Parser::commit_subcommand()
-{
-    if (m_tokens.is_empty())
-        return;
-    m_subcommands.append({ move(m_tokens), move(m_redirections) });
-}
-
-void Parser::do_pipe()
-{
-    m_redirections.append({ Redirection::Pipe, STDOUT_FILENO });
-    commit_subcommand();
-}
-
-void Parser::begin_redirect_read(int fd)
-{
-    m_redirections.append({ Redirection::FileRead, fd });
-}
-
-void Parser::begin_redirect_write(int fd)
-{
-    m_redirections.append({ Redirection::FileWrite, fd });
-}
-
-Vector<Subcommand> Parser::parse()
-{
-    for (int i = 0; i < m_input.length(); ++i) {
-        char ch = m_input.characters()[i];
-        switch (m_state) {
-        case State::Free:
-            if (ch == ' ') {
-                commit_token();
-                break;
-            }
-            if (ch == '|') {
-                commit_token();
-                if (m_tokens.is_empty()) {
-                    fprintf(stderr, "Syntax error: Nothing before pipe (|)\n");
-                    return { };
-                }
-                do_pipe();
-                break;
-            }
-            if (ch == '>') {
-                commit_token();
-                begin_redirect_write(STDOUT_FILENO);
-                m_state = State::InRedirectionPath;
-                break;
-            }
-            if (ch == '<') {
-                commit_token();
-                begin_redirect_read(STDIN_FILENO);
-                m_state = State::InRedirectionPath;
-                break;
-            }
-            if (ch == '\'') {
-                m_state = State::InSingleQuotes;
-                break;
-            }
-            if (ch == '\"') {
-                m_state = State::InDoubleQuotes;
-                break;
-            }
-            m_token.append(ch);
-            break;
-        case State::InRedirectionPath:
-            if (ch == '<') {
-                commit_token();
-                begin_redirect_read(STDIN_FILENO);
-                m_state = State::InRedirectionPath;
-                break;
-            }
-            if (ch == '>') {
-                commit_token();
-                begin_redirect_read(STDOUT_FILENO);
-                m_state = State::InRedirectionPath;
-                break;
-            }
-            if (ch == '|') {
-                commit_token();
-                if (m_tokens.is_empty()) {
-                    fprintf(stderr, "Syntax error: Nothing before pipe (|)\n");
-                    return { };
-                }
-                do_pipe();
-                m_state = State::Free;
-                break;
-            }
-            if (ch == ' ')
-                break;
-            m_token.append(ch);
-            break;
-        case State::InSingleQuotes:
-            if (ch == '\'') {
-                commit_token();
-                m_state = State::Free;
-                break;
-            }
-            m_token.append(ch);
-            break;
-        case State::InDoubleQuotes:
-            if (ch == '\"') {
-                commit_token();
-                m_state = State::Free;
-                break;
-            }
-            m_token.append(ch);
-            break;
-        };
-    }
-    commit_token();
-    commit_subcommand();
-
-    if (!m_subcommands.is_empty()) {
-        for (auto& redirection : m_subcommands.last().redirections) {
-            if (redirection.type == Redirection::Pipe) {
-                fprintf(stderr, "Syntax error: Nothing after last pipe (|)\n");
-                return { };
-            }
-        }
-    }
-
-    return move(m_subcommands);
-}
-
 class FileDescriptorCollector {
 public:
     FileDescriptorCollector() { }