diff options
author | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:08:07 +0900 |
---|---|---|
committer | DongHun Kwak <dh0128.kwak@samsung.com> | 2017-09-13 11:09:00 +0900 |
commit | b5c87084afaef42b2d058f68091be31988a6a874 (patch) | |
tree | adef9a65870a41181687e11d57fdf98e7629de3c /boost/process/detail/posix/basic_cmd.hpp | |
parent | 34bd32e225e2a8a94104489b31c42e5801cc1f4a (diff) | |
download | boost-b5c87084afaef42b2d058f68091be31988a6a874.tar.gz boost-b5c87084afaef42b2d058f68091be31988a6a874.tar.bz2 boost-b5c87084afaef42b2d058f68091be31988a6a874.zip |
Imported Upstream version 1.64.0upstream/1.64.0
Change-Id: Id9212edd016dd55f21172c427aa7894d1d24148b
Signed-off-by: DongHun Kwak <dh0128.kwak@samsung.com>
Diffstat (limited to 'boost/process/detail/posix/basic_cmd.hpp')
-rw-r--r-- | boost/process/detail/posix/basic_cmd.hpp | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/boost/process/detail/posix/basic_cmd.hpp b/boost/process/detail/posix/basic_cmd.hpp new file mode 100644 index 0000000000..eefcc5c53f --- /dev/null +++ b/boost/process/detail/posix/basic_cmd.hpp @@ -0,0 +1,177 @@ +// 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_BASIC_CMD_HPP_ +#define BOOST_PROCESS_DETAIL_POSIX_BASIC_CMD_HPP_ + +#include <boost/process/detail/posix/handler.hpp> +#include <boost/process/detail/posix/cmd.hpp> +#include <boost/algorithm/string/replace.hpp> +#include <boost/process/shell.hpp> +#include <boost/algorithm/string/trim.hpp> +#include <boost/algorithm/string/join.hpp> +#include <string> +#include <vector> + +namespace boost +{ +namespace process +{ +namespace detail +{ +namespace posix +{ + + +inline std::string build_cmd_shell(const std::string & exe, std::vector<std::string> && data) +{ + std::string st = exe; + for (auto & arg : data) + { + boost::replace_all(arg, "\"", "\\\""); + + auto it = std::find(arg.begin(), arg.end(), ' ');//contains space? + if (it != arg.end())//ok, contains spaces. + { + //the first one is put directly onto the output, + //because then I don't have to copy the whole string + arg.insert(arg.begin(), '"' ); + arg += '"'; //thats the post one. + } + + if (!st.empty())//first one does not need a preceeding space + st += ' '; + + st += arg; + } + return st ; +} + +inline std::vector<std::string> build_args(const std::string & data) +{ + std::vector<std::string> st; + + typedef std::string::const_iterator itr_t; + + //normal quotes outside can be stripped, inside ones marked as \" will be replaced. + auto make_entry = [](const itr_t & begin, const itr_t & end) + { + std::string data; + if ((*begin == '"') && (*(end-1) == '"')) + data.assign(begin+1, end-1); + else + data.assign(begin, end); + + boost::replace_all(data, "\\\"", "\""); + return data; + + }; + + bool in_quote = false; + + auto part_beg = data.cbegin(); + auto itr = data.cbegin(); + + for (; itr != data.cend(); itr++) + { + if (*itr == '"') + in_quote ^= true; + + if (!in_quote && (*itr == ' ')) + { + //alright, got a space + + if ((itr != data.cbegin()) && (*(itr -1) != ' ' )) + st.push_back(make_entry(part_beg, itr)); + + part_beg = itr+1; + } + } + if (part_beg != itr) + st.emplace_back(make_entry(part_beg, itr)); + + + return st; +} + +template<typename Char> +struct exe_cmd_init; + +template<> +struct exe_cmd_init<char> : boost::process::detail::api::handler_base_ext +{ + exe_cmd_init(const exe_cmd_init & ) = delete; + exe_cmd_init(exe_cmd_init && ) = default; + exe_cmd_init(std::string && exe, std::vector<std::string> && args) + : exe(std::move(exe)), args(std::move(args)) {}; + template <class Executor> + void on_setup(Executor& exec) + { + if (exe.empty()) //cmd style + { + exec.exe = args.front().c_str(); + exec.cmd_style = true; + } + else + exec.exe = &exe.front(); + + + if (!args.empty()) + { + cmd_impl = make_cmd(); + exec.cmd_line = cmd_impl.data(); + } + } + static exe_cmd_init exe_args(std::string && exe, std::vector<std::string> && args) {return exe_cmd_init(std::move(exe), std::move(args));} + static exe_cmd_init cmd (std::string && cmd) + { + auto args = build_args(cmd); + return exe_cmd_init({}, std::move(args)); + } + + static exe_cmd_init exe_args_shell(std::string&& exe, std::vector<std::string> && args) + { + auto cmd = build_cmd_shell(std::move(exe), std::move(args)); + + std::vector<std::string> args_ = {"-c", std::move(cmd)}; + std::string sh = shell().string(); + + return exe_cmd_init(std::move(sh), std::move(args_)); + } + static exe_cmd_init cmd_shell(std::string&& cmd) + { + std::vector<std::string> args = {"-c", "\"" + cmd + "\""}; + std::string sh = shell().string(); + + return exe_cmd_init( + std::move(sh), + {std::move(args)}); + } +private: + inline std::vector<char*> make_cmd(); + std::string exe; + std::vector<std::string> args; + std::vector<char*> cmd_impl; +}; + +std::vector<char*> exe_cmd_init<char>::make_cmd() +{ + std::vector<char*> vec; + if (!exe.empty()) + vec.push_back(&exe.front()); + + for (auto & v : args) + vec.push_back(&v.front()); + + vec.push_back(nullptr); + + return vec; +} + + +}}}} + +#endif |