]> git.proxmox.com Git - ceph.git/blob - ceph/src/boost/boost/process/detail/basic_cmd.hpp
update sources to v12.2.3
[ceph.git] / ceph / src / boost / boost / process / detail / basic_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_BASIC_CMD_HPP_
8 #define BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
9
10 #include <boost/process/detail/config.hpp>
11
12 #include <boost/process/detail/handler_base.hpp>
13 #include <boost/process/detail/traits/cmd_or_exe.hpp>
14 #include <boost/process/detail/traits/wchar_t.hpp>
15
16 #if defined( BOOST_WINDOWS_API )
17 #include <boost/process/detail/windows/basic_cmd.hpp>
18 #include <boost/process/detail/windows/cmd.hpp>
19 #elif defined( BOOST_POSIX_API )
20 #include <boost/process/detail/posix/basic_cmd.hpp>
21 #include <boost/process/detail/posix/cmd.hpp>
22 #endif
23
24 #include <boost/process/shell.hpp>
25
26 #include <iterator>
27
28
29 namespace boost { namespace process { namespace detail {
30
31 template<typename Char>
32 struct exe_setter_
33 {
34 typedef Char value_type;
35 typedef std::basic_string<Char> string_type;
36
37 string_type exe_;
38 exe_setter_(string_type && str) : exe_(std::move(str)) {}
39 exe_setter_(const string_type & str) : exe_(str) {}
40 };
41
42 template<> struct is_wchar_t<exe_setter_<wchar_t>> : std::true_type {};
43
44
45 template<>
46 struct char_converter<char, exe_setter_<wchar_t>>
47 {
48 static exe_setter_<char> conv(const exe_setter_<wchar_t> & in)
49 {
50 return {::boost::process::detail::convert(in.exe_)};
51 }
52 };
53
54 template<>
55 struct char_converter<wchar_t, exe_setter_<char>>
56 {
57 static exe_setter_<wchar_t> conv(const exe_setter_<char> & in)
58 {
59 return {::boost::process::detail::convert(in.exe_)};
60 }
61 };
62
63
64
65 template <typename Char, bool Append >
66 struct arg_setter_
67 {
68 using value_type = Char;
69 using string_type = std::basic_string<value_type>;
70 std::vector<string_type> _args;
71
72 typedef typename std::vector<string_type>::iterator iterator;
73 typedef typename std::vector<string_type>::const_iterator const_iterator;
74
75 template<typename Iterator>
76 arg_setter_(Iterator && begin, Iterator && end) : _args(begin, end) {}
77
78 template<typename Range>
79 arg_setter_(Range && str) :
80 _args(std::begin(str),
81 std::end(str)) {}
82
83 iterator begin() {return _args.begin();}
84 iterator end() {return _args.end();}
85 const_iterator begin() const {return _args.begin();}
86 const_iterator end() const {return _args.end();}
87 arg_setter_(string_type & str) : _args{{str}} {}
88 arg_setter_(string_type && s) : _args({std::move(s)}) {}
89 arg_setter_(const string_type & s) : _args({s}) {}
90 arg_setter_(const value_type* s) : _args({std::move(s)}) {}
91
92 template<std::size_t Size>
93 arg_setter_(const value_type (&s) [Size]) : _args({s}) {}
94 };
95
96 template<> struct is_wchar_t<arg_setter_<wchar_t, true >> : std::true_type {};
97 template<> struct is_wchar_t<arg_setter_<wchar_t, false>> : std::true_type {};
98
99 template<>
100 struct char_converter<char, arg_setter_<wchar_t, true>>
101 {
102 static arg_setter_<char, true> conv(const arg_setter_<wchar_t, true> & in)
103 {
104 std::vector<std::string> vec(in._args.size());
105 std::transform(in._args.begin(), in._args.end(), vec.begin(),
106 [](const std::wstring & ws)
107 {
108 return ::boost::process::detail::convert(ws);
109 });
110 return {vec};
111 }
112 };
113
114 template<>
115 struct char_converter<wchar_t, arg_setter_<char, true>>
116 {
117 static arg_setter_<wchar_t, true> conv(const arg_setter_<char, true> & in)
118 {
119 std::vector<std::wstring> vec(in._args.size());
120 std::transform(in._args.begin(), in._args.end(), vec.begin(),
121 [](const std::string & ws)
122 {
123 return ::boost::process::detail::convert(ws);
124 });
125
126 return {vec};
127 }
128 };
129
130 template<>
131 struct char_converter<char, arg_setter_<wchar_t, false>>
132 {
133 static arg_setter_<char, false> conv(const arg_setter_<wchar_t, false> & in)
134 {
135 std::vector<std::string> vec(in._args.size());
136 std::transform(in._args.begin(), in._args.end(), vec.begin(),
137 [](const std::wstring & ws)
138 {
139 return ::boost::process::detail::convert(ws);
140 });
141 return {vec}; }
142 };
143
144 template<>
145 struct char_converter<wchar_t, arg_setter_<char, false>>
146 {
147 static arg_setter_<wchar_t, false> conv(const arg_setter_<char, false> & in)
148 {
149 std::vector<std::wstring> vec(in._args.size());
150 std::transform(in._args.begin(), in._args.end(), vec.begin(),
151 [](const std::string & ws)
152 {
153 return ::boost::process::detail::convert(ws);
154 });
155 return {vec};
156 }
157 };
158
159 using api::exe_cmd_init;
160
161 template<typename Char>
162 struct exe_builder
163 {
164 //set by path, because that will not be interpreted as a cmd
165 bool not_cmd = false;
166 bool shell = false;
167 using string_type = std::basic_string<Char>;
168 string_type exe;
169 std::vector<string_type> args;
170
171 void operator()(const boost::filesystem::path & data)
172 {
173 not_cmd = true;
174 if (exe.empty())
175 exe = data.native();
176 else
177 args.push_back(data.native());
178 }
179
180 void operator()(const string_type & data)
181 {
182 if (exe.empty())
183 exe = data;
184 else
185 args.push_back(data);
186 }
187 void operator()(const Char* data)
188 {
189 if (exe.empty())
190 exe = data;
191 else
192 args.push_back(data);
193 }
194 void operator()(shell_) {shell = true;}
195 void operator()(std::vector<string_type> && data)
196 {
197 if (data.empty())
198 return;
199
200 auto itr = std::make_move_iterator(data.begin());
201 auto end = std::make_move_iterator(data.end());
202
203 if (exe.empty())
204 {
205 exe = *itr;
206 itr++;
207 }
208 args.insert(args.end(), itr, end);
209 }
210
211 void operator()(const std::vector<string_type> & data)
212 {
213 if (data.empty())
214 return;
215
216 auto itr = data.begin();
217 auto end = data.end();
218
219 if (exe.empty())
220 {
221 exe = *itr;
222 itr++;
223 }
224 args.insert(args.end(), itr, end);
225 }
226 void operator()(exe_setter_<Char> && data)
227 {
228 not_cmd = true;
229 exe = std::move(data.exe_);
230 }
231 void operator()(const exe_setter_<Char> & data)
232 {
233 not_cmd = true;
234 exe = data.exe_;
235 }
236 void operator()(arg_setter_<Char, false> && data)
237 {
238 args.assign(
239 std::make_move_iterator(data._args.begin()),
240 std::make_move_iterator(data._args.end()));
241 }
242 void operator()(arg_setter_<Char, true> && data)
243 {
244 args.insert(args.end(),
245 std::make_move_iterator(data._args.begin()),
246 std::make_move_iterator(data._args.end()));
247 }
248 void operator()(const arg_setter_<Char, false> & data)
249 {
250 args.assign(data._args.begin(), data._args.end());
251 }
252 void operator()(const arg_setter_<Char, true> & data)
253 {
254 args.insert(args.end(), data._args.begin(), data._args.end());
255 }
256
257 api::exe_cmd_init<Char> get_initializer()
258 {
259 if (not_cmd || !args.empty())
260 {
261 if (shell)
262 return api::exe_cmd_init<Char>::exe_args_shell(std::move(exe), std::move(args));
263 else
264 return api::exe_cmd_init<Char>::exe_args(std::move(exe), std::move(args));
265 }
266 else
267 if (shell)
268 return api::exe_cmd_init<Char>::cmd_shell(std::move(exe));
269 else
270 return api::exe_cmd_init<Char>::cmd(std::move(exe));
271
272 }
273 typedef api::exe_cmd_init<Char> result_type;
274 };
275
276 template<>
277 struct initializer_builder<cmd_or_exe_tag<char>>
278 {
279 typedef exe_builder<char> type;
280 };
281
282 template<>
283 struct initializer_builder<cmd_or_exe_tag<wchar_t>>
284 {
285 typedef exe_builder<wchar_t> type;
286 };
287
288 }}}
289
290
291
292 #endif /* BOOST_PROCESS_DETAIL_EXE_BUILDER_HPP_ */