// Copyright (c) 2016 Klemens D. Morgenstern // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) #ifndef BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_ #define BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_ #include #include #include #include namespace boost { namespace process { namespace detail { namespace posix { template inline std::vector> build_cmd(const std::basic_string & value) { std::vector> ret; bool in_quotes = false; auto beg = value.begin(); for (auto itr = value.begin(); itr != value.end(); itr++) { if (*itr == quote_sign()) in_quotes = !in_quotes; if (!in_quotes && (*itr == space_sign())) { if (itr != beg) { ret.emplace_back(beg, itr); beg = itr + 1; } } } if (beg != value.end()) ret.emplace_back(beg, value.end()); return ret; } template struct cmd_setter_ : handler_base_ext { typedef Char value_type; typedef std::basic_string string_type; cmd_setter_(string_type && cmd_line) : _cmd_line(api::build_cmd(std::move(cmd_line))) {} cmd_setter_(const string_type & cmd_line) : _cmd_line(api::build_cmd(cmd_line)) {} template void on_setup(Executor& exec) { exec.exe = _cmd_impl.front(); exec.cmd_line = &_cmd_impl.front(); exec.cmd_style = true; } string_type str() const { string_type ret; std::size_t size = 0; for (auto & cmd : _cmd_line) size += cmd.size() + 1; ret.reserve(size -1); for (auto & cmd : _cmd_line) { if (!ret.empty()) ret += equal_sign(); ret += cmd; } return ret; } private: static inline std::vector make_cmd(std::vector & args); std::vector _cmd_line; std::vector _cmd_impl = make_cmd(_cmd_line); }; template std::vector cmd_setter_::make_cmd(std::vector> & args) { std::vector vec; for (auto & v : args) vec.push_back(&v.front()); vec.push_back(nullptr); return vec; } }}}} #endif