diff --git a/src/Snel.cpp b/src/Snel.cpp index 2977a7c..65cbced 100755 --- a/src/Snel.cpp +++ b/src/Snel.cpp @@ -9,7 +9,7 @@ int main(int argc, char* argv[]) try { std::ifstream file(argv[1]); while (std::getline (file, line, '\n')) { - s.parse(line).execute(); + s.parse(snel::filter(line)).execute(); } } else { // interactive mode @@ -19,7 +19,7 @@ int main(int argc, char* argv[]) try { std::getline (std::cin, line, '\n'); if (line == "quit") break; - s.parse(line).execute(); + s.parse(snel::filter(line)).execute(); } while (1); } return 0; diff --git a/src/sequencer.cpp b/src/sequencer.cpp index 5291155..a637169 100755 --- a/src/sequencer.cpp +++ b/src/sequencer.cpp @@ -35,6 +35,28 @@ namespace snel { } } + std::string filter (const std::string in) { + std::string out; + char prev {0}, cur, next {0}; + + for (auto i = in.begin(); i != in.end() ; ++i) { + cur = *i; + if (cur == '|') { + if (prev != ' ') out += ' '; + next = *++i; + if (next == '|' || next == ' ') { + out += cur; cur = next; // syntax ok + } + else { + // syntax problem, insert a space + out += cur; out += ' '; cur = next; + } + } + prev = cur; + out += cur; + } + return out; + } /* * ========== ArgList ========== */ @@ -44,7 +66,7 @@ namespace snel { delete[] p; } } - ArgList& ArgList::push_back(const std::basic_string& item) { + ArgList& ArgList::push_back(const std::string& item) { vtype it = new type[item.length()+1]; // get data @@ -92,7 +114,7 @@ namespace snel { } Child& Child::make_arguments () { bool in{false}, out{false}, err{false}; - bool CanRedirectIn = (pipe_.from) ? true : false; + bool CanRedirectIn = (!pipe_.from) ? true : false; bool CanRedirectOut = (!pipe_.to) ? true : false; for (auto& t: command) { @@ -132,8 +154,10 @@ namespace snel { return *this; } - bool Child::execute(const Child* previous) { + bool Child::execute(std::vector::iterator it, bool first) { bool stop = {false}; + if (!first) --it; + Child& previous = *it; // Check parent redirection redirect_std_if (filenames[STDIN_], STDIN_); @@ -156,10 +180,9 @@ namespace snel { if ((dup2(pipe_.fd[1], STDOUT_)) == -1) // redirect output throw Error("Child pipe[to]: Can not redirect through pipe"); } - else if ((previous!= nullptr) && pipe_.from) { // receiveing child - std::cout << "from[0]=" << previous->pipe().fd[0] << " from[1]=" << previous->pipe().fd[1]<< std::endl; - close (previous->pipe().fd[1]); // close the write end - if ((dup2(previous->pipe().fd[0], STDIN_)) == -1) // redirect input + else if (!first && pipe_.from) { // receiveing child + close (previous.pipe().fd[1]); // close the write end + if ((dup2(previous.pipe().fd[0], STDIN_)) == -1) // redirect input throw Error("Child pipe[from]: Can not redirect through pipe"); } execvp(arguments.front(), arguments.data()); @@ -169,7 +192,8 @@ namespace snel { } else { // parent if (pipe_.to) close (pipe_.fd[1]); - else if (pipe_.from) close (previous->pipe().fd[0]); + else if (!first && pipe_.from) + close (previous.pipe().fd[0]); int exit_status; waitpid(pid, &exit_status, 0); // wait child process to finish @@ -233,14 +257,16 @@ namespace snel { } Sequencer& Sequencer::execute() { - for (auto& batch : seq_) + for (auto& batch : seq_) { + bool first; + first = true; for (auto it = batch.begin() ; it != batch.end(); ++it) { Child& command = *it; - Child p = (it != batch.begin()) ? std::prev(it) : Child{}; - if (command.make_arguments().execute(p)) + if (command.make_arguments().execute(it, first)) break; - + first = false; } + } seq_.clear(); return *this; } diff --git a/src/sequencer.h b/src/sequencer.h index 2f38352..f3311b7 100755 --- a/src/sequencer.h +++ b/src/sequencer.h @@ -31,11 +31,13 @@ namespace snel { constexpr fd_t STDOUT_ = STDOUT_FILENO; constexpr fd_t STDERR_ = STDERR_FILENO; + std::string filter (const std::string in); + /*! * */ struct ArgList { - using type = char; // Basic data type + using type = typename std::string::value_type; // Basic data type using vtype = type*; // Vector type using vtype_ptr = vtype*; // Pointer to vector type @@ -44,7 +46,7 @@ namespace snel { ArgList(const ArgList&) = default; ArgList(ArgList&&) = default; - ArgList& push_back(const std::basic_string& item); + ArgList& push_back(const std::string& item); vtype front () { return args_.front(); } size_t size () { return args_.size(); } @@ -73,12 +75,12 @@ namespace snel { public: ~Child (); - Child () noexcept = default; + Child () = default; Child (const command_t& c) : command{c} { } Child (command_t&& c) : command{std::move(c)} { } Child& make_arguments (); - bool execute (const Child* previous); + bool execute(std::vector::iterator it, bool first); Pipe& pipe() { return pipe_; } private: void redirect_std_if(std::string fn, fd_t std_fd);