diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d67022..7b68e5c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,9 @@ macro(RAGEL_TARGET Name Input Output) endmacro() + + + #add_custom_command( # OUTPUT mpw-shell-read.cpp # COMMAND ragel -p -G2 -o mpw-shell-read.cpp "${CMAKE_CURRENT_SOURCE_DIR}/mpw-shell-read.rl" @@ -62,6 +65,14 @@ RAGEL_TARGET(mpw-shell-read mpw-shell-read.rl mpw-shell-read.cpp COMPILE_FLAGS " RAGEL_TARGET(phase1 phase1.rl phase1.cpp COMPILE_FLAGS "-p -G2") RAGEL_TARGET(phase2 phase2.rl phase2.cpp COMPILE_FLAGS "-p -G2") +add_custom_command( + OUTPUT phase2-parser.cpp phase2-parser.h + COMMAND lemon++ -Tlempar.cxx phase2-parser.lemon + COMMAND mv phase2-parser.cpp ${CMAKE_CURRENT_BINARY_DIR}/ + MAIN_DEPENDENCY phase2-parser.lemon + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} +) + add_custom_command( OUTPUT mpw-shell-expand.cpp COMMAND ragel -p -G2 -o mpw-shell-expand.cpp "${CMAKE_CURRENT_SOURCE_DIR}/mpw-shell-expand.rl" @@ -107,7 +118,7 @@ add_custom_command( add_executable(mpw-shell mpw-shell.cpp mpw-shell-read.cpp mpw-shell-token.cpp mpw-shell-expand.cpp mpw-shell-execute.cpp mpw-shell-builtins.cpp mpw-shell-parser.cpp value.cpp mpw-shell-quote.cpp - phase1.cpp phase2.cpp ) + phase1.cpp phase2.cpp phase2-parser.cpp command.cpp) # all this for -std=c++14 set_property (TARGET mpw-shell PROPERTY CXX_STANDARD 14) diff --git a/mpw-shell.cpp b/mpw-shell.cpp index 3881daf..31f8b04 100644 --- a/mpw-shell.cpp +++ b/mpw-shell.cpp @@ -7,10 +7,14 @@ #include #include #include +#include +#define NOCOMMAND #include "mpw-shell.h" - +#include "phase1.h" +#include "phase2.h" +#include "command.h" std::unordered_map Environment; @@ -24,6 +28,37 @@ void init(void) { Environment.emplace("exit", std::string("1")); // terminate script on error. } +int read_stdin(phase1 &p) { + + unsigned char buffer[2048]; + ssize_t size; + + for (;;) { + size = read(STDIN_FILENO, buffer, sizeof(buffer)); + if (size == 0) break; + if (size < 0) { + if (errno == EINTR) continue; + perror("read: "); + return -1; + } + try { + p.process(buffer, buffer + size); + } catch(std::exception &ex) { + fprintf(stderr, "%s\n", ex.what()); + p.reset(); + } + } + + try { + p.finish(); + } catch(std::exception &ex) { + fprintf(stderr, "%s\n", ex.what()); + p.reset(); + } + + return 0; +} + int main(int argc, char **argv) { init(); @@ -31,6 +66,17 @@ int main(int argc, char **argv) { command_ptr head; + phase1 p1; + phase2 p2; + p1 >>= [&p2](std::string &&s) { + + fprintf(stdout, " -> %s\n", s.c_str()); + p2.process(s); + }; + + read_stdin(p1); + +/* try { head = read_fd(0); } catch (std::exception &ex) { @@ -46,5 +92,5 @@ int main(int argc, char **argv) { fprintf(stderr, "%s\n", ex.what()); exit(1); } - +*/ } diff --git a/mpw-shell.h b/mpw-shell.h index 48f662b..9626620 100644 --- a/mpw-shell.h +++ b/mpw-shell.h @@ -7,9 +7,6 @@ #include #include -class command; -typedef std::shared_ptr command_ptr; -typedef std::weak_ptr weak_command_ptr; const unsigned char escape = 0xb6; @@ -46,6 +43,8 @@ private: extern std::unordered_map Environment; +#ifndef NOCOMMAND + enum { command_if = 1, command_else, @@ -55,6 +54,10 @@ enum { command_evaluate, }; +class command; +typedef std::shared_ptr command_ptr; +typedef std::weak_ptr weak_command_ptr; + class command { public: unsigned type = 0; @@ -86,6 +89,12 @@ class command { }; +command_ptr read_fd(int fd); +command_ptr read_file(const std::string &); +command_ptr read_string(const std::string &); +int execute(command_ptr cmd); + +#endif class token { public: @@ -122,9 +131,6 @@ public: }; -command_ptr read_fd(int fd); -command_ptr read_file(const std::string &); -command_ptr read_string(const std::string &); std::vector tokenize(const std::string &s, bool eval = false); std::string expand_vars(const std::string &s, const std::unordered_map &env); @@ -140,7 +146,6 @@ class fdmask; void parse_tokens(std::vector &&tokens, process &p); -int execute(command_ptr cmd); int32_t evaluate_expression(const std::string &name, std::vector &&tokens);