From 654ffdef9182677983a4b4801027b483a55a7917 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 22 Oct 2019 22:15:43 +0200 Subject: [PATCH] HackStudio: Add a simple "Build" action Pressing Ctrl+B now invokes "make" in the project directory and routes the output from the make command to the little terminal widget. --- DevTools/HackStudio/TerminalWrapper.cpp | 52 +++++++++++++++++++------ DevTools/HackStudio/TerminalWrapper.h | 3 ++ DevTools/HackStudio/main.cpp | 13 +++++++ 3 files changed, 56 insertions(+), 12 deletions(-) diff --git a/DevTools/HackStudio/TerminalWrapper.cpp b/DevTools/HackStudio/TerminalWrapper.cpp index 9500b518dd..26c80bfa46 100644 --- a/DevTools/HackStudio/TerminalWrapper.cpp +++ b/DevTools/HackStudio/TerminalWrapper.cpp @@ -2,17 +2,53 @@ #include #include #include +#include #include #include #include #include #include +#include #include -static void run_command(int ptm_fd, const String& command) +void TerminalWrapper::run_command(const String& command) { - pid_t pid = fork(); - if (pid == 0) { + if (m_pid != -1) { + GMessageBox::show( + "A command is already running in this TerminalWrapper", + "Can't run command", + GMessageBox::Type::Error, + GMessageBox::InputType::OK, + window()); + return; + } + + int ptm_fd = open("/dev/ptmx", O_RDWR); + if (ptm_fd < 0) { + perror("open(ptmx)"); + ASSERT_NOT_REACHED(); + } + + m_terminal_widget->set_pty_master_fd(ptm_fd); + m_terminal_widget->on_command_exit = [this] { + int wstatus; + int rc = waitpid(m_pid, &wstatus, 0); + if (rc < 0) { + perror("waitpid"); + ASSERT_NOT_REACHED(); + } + if (WIFEXITED(wstatus)) { + m_terminal_widget->inject_string(String::format("\033[%d;1m(Command exited with code %d)\033[0m\n", wstatus == 0 ? 32 : 31, WEXITSTATUS(wstatus))); + } else if (WIFSTOPPED(wstatus)) { + m_terminal_widget->inject_string(String::format("\033[34;1m(Command stopped!)\033[0m\n")); + } else if (WIFSIGNALED(wstatus)) { + m_terminal_widget->inject_string(String::format("\033[34;1m(Command signaled with %s!)\033[0m\n", strsignal(WTERMSIG(wstatus)))); + } + m_pid = -1; + }; + + m_pid = fork(); + if (m_pid == 0) { const char* tty_name = ptsname(ptm_fd); if (!tty_name) { perror("ptsname"); @@ -77,16 +113,8 @@ TerminalWrapper::TerminalWrapper(GWidget* parent) { set_layout(make(Orientation::Vertical)); - int ptm_fd = open("/dev/ptmx", O_RDWR); - if (ptm_fd < 0) { - perror("open(ptmx)"); - ASSERT_NOT_REACHED(); - } - - run_command(ptm_fd, "/bin/Shell"); - RefPtr config = CConfigFile::get_for_app("Terminal"); - m_terminal_widget = TerminalWidget::construct(ptm_fd, false, config); + m_terminal_widget = TerminalWidget::construct(-1, false, config); add_child(*m_terminal_widget); } diff --git a/DevTools/HackStudio/TerminalWrapper.h b/DevTools/HackStudio/TerminalWrapper.h index c36e421a1f..90ca7c44e4 100644 --- a/DevTools/HackStudio/TerminalWrapper.h +++ b/DevTools/HackStudio/TerminalWrapper.h @@ -9,8 +9,11 @@ class TerminalWrapper final : public GWidget { public: virtual ~TerminalWrapper() override; + void run_command(const String&); + private: explicit TerminalWrapper(GWidget* parent); RefPtr m_terminal_widget; + pid_t m_pid { -1 }; }; diff --git a/DevTools/HackStudio/main.cpp b/DevTools/HackStudio/main.cpp index eabfd0e122..7548c2b090 100644 --- a/DevTools/HackStudio/main.cpp +++ b/DevTools/HackStudio/main.cpp @@ -21,6 +21,8 @@ String g_currently_open_file; +static void build(TerminalWrapper&); + int main(int argc, char** argv) { GApplication app(argc, argv); @@ -97,6 +99,12 @@ int main(int argc, char** argv) })); menubar->add_menu(move(app_menu)); + auto build_menu = make("Build"); + build_menu->add_action(GAction::create("Build", { Mod_Ctrl, Key_B }, [&](auto&) { + build(terminal_wrapper); + })); + menubar->add_menu(move(build_menu)); + auto small_icon = GraphicsBitmap::load_from_file("/res/icons/16x16/app-hack-studio.png"); auto help_menu = make("Help"); @@ -112,3 +120,8 @@ int main(int argc, char** argv) window->show(); return app.exec(); } + +void build(TerminalWrapper& wrapper) +{ + wrapper.run_command("make"); +}