1 // Copyright (c) 2016 Klemens D. Morgenstern 2 // 3 // Distributed under the Boost Software License, Version 1.0. (See accompanying 4 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) 5 6 7 #ifndef BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_ 8 #define BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_ 9 10 #include <boost/process/detail/config.hpp> 11 #include <boost/process/detail/posix/handler.hpp> 12 #include <string> 13 #include <vector> 14 15 namespace boost 16 { 17 namespace process 18 { 19 namespace detail 20 { 21 namespace posix 22 { 23 24 25 template<typename Char> build_cmd(const std::basic_string<Char> & value)26inline std::vector<std::basic_string<Char>> build_cmd(const std::basic_string<Char> & value) 27 { 28 std::vector<std::basic_string<Char>> ret; 29 30 bool in_quotes = false; 31 auto beg = value.begin(); 32 for (auto itr = value.begin(); itr != value.end(); itr++) 33 { 34 if (*itr == quote_sign<Char>()) 35 in_quotes = !in_quotes; 36 37 if (!in_quotes && (*itr == space_sign<Char>())) 38 { 39 if (itr != beg) 40 { 41 ret.emplace_back(beg, itr); 42 beg = itr + 1; 43 } 44 } 45 } 46 if (beg != value.end()) 47 ret.emplace_back(beg, value.end()); 48 49 return ret; 50 } 51 52 template<typename Char> 53 struct cmd_setter_ : handler_base_ext 54 { 55 typedef Char value_type; 56 typedef std::basic_string<value_type> string_type; 57 cmd_setter_boost::process::detail::posix::cmd_setter_58 cmd_setter_(string_type && cmd_line) : _cmd_line(api::build_cmd(std::move(cmd_line))) {} cmd_setter_boost::process::detail::posix::cmd_setter_59 cmd_setter_(const string_type & cmd_line) : _cmd_line(api::build_cmd(cmd_line)) {} 60 template <class Executor> on_setupboost::process::detail::posix::cmd_setter_61 void on_setup(Executor& exec) 62 { 63 exec.exe = _cmd_impl.front(); 64 exec.cmd_line = &_cmd_impl.front(); 65 exec.cmd_style = true; 66 } strboost::process::detail::posix::cmd_setter_67 string_type str() const 68 { 69 string_type ret; 70 std::size_t size = 0; 71 for (auto & cmd : _cmd_line) 72 size += cmd.size() + 1; 73 ret.reserve(size -1); 74 75 for (auto & cmd : _cmd_line) 76 { 77 if (!ret.empty()) 78 ret += equal_sign<Char>(); 79 ret += cmd; 80 } 81 return ret; 82 } 83 private: 84 static inline std::vector<Char*> make_cmd(std::vector<string_type> & args); 85 std::vector<string_type> _cmd_line; 86 std::vector<Char*> _cmd_impl = make_cmd(_cmd_line); 87 }; 88 89 template<typename Char> make_cmd(std::vector<std::basic_string<Char>> & args)90std::vector<Char*> cmd_setter_<Char>::make_cmd(std::vector<std::basic_string<Char>> & args) 91 { 92 std::vector<Char*> vec; 93 94 for (auto & v : args) 95 vec.push_back(&v.front()); 96 97 vec.push_back(nullptr); 98 99 return vec; 100 } 101 102 }}}} 103 104 #endif 105