Imported Upstream version 1.64.0
[platform/upstream/boost.git] / boost / process / detail / posix / cmd.hpp
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>
26 inline 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
58     cmd_setter_(string_type && cmd_line)      : _cmd_line(api::build_cmd(std::move(cmd_line))) {}
59     cmd_setter_(const string_type & cmd_line) : _cmd_line(api::build_cmd(cmd_line)) {}
60     template <class Executor>
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     }
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>
90 std::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