File indexing completed on 2025-01-18 09:50:09
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
0008 #define BOOST_PROCESS_DETAIL_BASIC_CMD_HPP_
0009
0010 #include <boost/process/detail/config.hpp>
0011
0012 #include <boost/process/detail/handler_base.hpp>
0013 #include <boost/process/detail/traits/cmd_or_exe.hpp>
0014 #include <boost/process/detail/traits/wchar_t.hpp>
0015
0016 #if defined( BOOST_WINDOWS_API )
0017 #include <boost/process/detail/windows/basic_cmd.hpp>
0018 #include <boost/process/detail/windows/cmd.hpp>
0019 #elif defined( BOOST_POSIX_API )
0020 #include <boost/process/detail/posix/basic_cmd.hpp>
0021 #include <boost/process/detail/posix/cmd.hpp>
0022 #endif
0023
0024 #include <boost/process/shell.hpp>
0025
0026 #include <iterator>
0027
0028
0029 namespace boost { namespace process { namespace detail {
0030
0031 template<typename Char>
0032 struct exe_setter_
0033 {
0034 typedef Char value_type;
0035 typedef std::basic_string<Char> string_type;
0036
0037 string_type exe_;
0038 exe_setter_(string_type && str) : exe_(std::move(str)) {}
0039 exe_setter_(const string_type & str) : exe_(str) {}
0040 };
0041
0042 template<> struct is_wchar_t<exe_setter_<wchar_t>> : std::true_type {};
0043
0044
0045 template<>
0046 struct char_converter<char, exe_setter_<wchar_t>>
0047 {
0048 static exe_setter_<char> conv(const exe_setter_<wchar_t> & in)
0049 {
0050 return {::boost::process::detail::convert(in.exe_)};
0051 }
0052 };
0053
0054 template<>
0055 struct char_converter<wchar_t, exe_setter_<char>>
0056 {
0057 static exe_setter_<wchar_t> conv(const exe_setter_<char> & in)
0058 {
0059 return {::boost::process::detail::convert(in.exe_)};
0060 }
0061 };
0062
0063
0064
0065 template <typename Char, bool Append >
0066 struct arg_setter_
0067 {
0068 using value_type = Char;
0069 using string_type = std::basic_string<value_type>;
0070 std::vector<string_type> _args;
0071
0072 typedef typename std::vector<string_type>::iterator iterator;
0073 typedef typename std::vector<string_type>::const_iterator const_iterator;
0074
0075 template<typename Iterator>
0076 arg_setter_(Iterator && begin, Iterator && end) : _args(begin, end) {}
0077
0078 template<typename Range>
0079 arg_setter_(Range && str) :
0080 _args(std::begin(str),
0081 std::end(str)) {}
0082
0083 iterator begin() {return _args.begin();}
0084 iterator end() {return _args.end();}
0085 const_iterator begin() const {return _args.begin();}
0086 const_iterator end() const {return _args.end();}
0087 arg_setter_(string_type & str) : _args{{str}} {}
0088 arg_setter_(string_type && s) : _args({std::move(s)}) {}
0089 arg_setter_(const string_type & s) : _args({s}) {}
0090 arg_setter_(const value_type* s) : _args({std::move(s)}) {}
0091
0092 template<std::size_t Size>
0093 arg_setter_(const value_type (&s) [Size]) : _args({s}) {}
0094 };
0095
0096 template<> struct is_wchar_t<arg_setter_<wchar_t, true >> : std::true_type {};
0097 template<> struct is_wchar_t<arg_setter_<wchar_t, false>> : std::true_type {};
0098
0099 template<>
0100 struct char_converter<char, arg_setter_<wchar_t, true>>
0101 {
0102 static arg_setter_<char, true> conv(const arg_setter_<wchar_t, true> & in)
0103 {
0104 std::vector<std::string> vec(in._args.size());
0105 std::transform(in._args.begin(), in._args.end(), vec.begin(),
0106 [](const std::wstring & ws)
0107 {
0108 return ::boost::process::detail::convert(ws);
0109 });
0110 return {vec};
0111 }
0112 };
0113
0114 template<>
0115 struct char_converter<wchar_t, arg_setter_<char, true>>
0116 {
0117 static arg_setter_<wchar_t, true> conv(const arg_setter_<char, true> & in)
0118 {
0119 std::vector<std::wstring> vec(in._args.size());
0120 std::transform(in._args.begin(), in._args.end(), vec.begin(),
0121 [](const std::string & ws)
0122 {
0123 return ::boost::process::detail::convert(ws);
0124 });
0125
0126 return {vec};
0127 }
0128 };
0129
0130 template<>
0131 struct char_converter<char, arg_setter_<wchar_t, false>>
0132 {
0133 static arg_setter_<char, false> conv(const arg_setter_<wchar_t, false> & in)
0134 {
0135 std::vector<std::string> vec(in._args.size());
0136 std::transform(in._args.begin(), in._args.end(), vec.begin(),
0137 [](const std::wstring & ws)
0138 {
0139 return ::boost::process::detail::convert(ws);
0140 });
0141 return {vec}; }
0142 };
0143
0144 template<>
0145 struct char_converter<wchar_t, arg_setter_<char, false>>
0146 {
0147 static arg_setter_<wchar_t, false> conv(const arg_setter_<char, false> & in)
0148 {
0149 std::vector<std::wstring> vec(in._args.size());
0150 std::transform(in._args.begin(), in._args.end(), vec.begin(),
0151 [](const std::string & ws)
0152 {
0153 return ::boost::process::detail::convert(ws);
0154 });
0155 return {vec};
0156 }
0157 };
0158
0159 using api::exe_cmd_init;
0160
0161 template<typename Char>
0162 struct exe_builder
0163 {
0164
0165 bool not_cmd = false;
0166 bool shell = false;
0167 using string_type = std::basic_string<Char>;
0168 string_type exe;
0169 std::vector<string_type> args;
0170
0171 void operator()(const boost::process::filesystem::path & data)
0172 {
0173 not_cmd = true;
0174 if (exe.empty())
0175 exe = data.native();
0176 else
0177 args.push_back(data.native());
0178 }
0179
0180 void operator()(const string_type & data)
0181 {
0182 if (exe.empty())
0183 exe = data;
0184 else
0185 args.push_back(data);
0186 }
0187 void operator()(const Char* data)
0188 {
0189 if (exe.empty())
0190 exe = data;
0191 else
0192 args.push_back(data);
0193 }
0194 void operator()(shell_) {shell = true;}
0195 void operator()(std::vector<string_type> && data)
0196 {
0197 if (data.empty())
0198 return;
0199
0200 auto itr = std::make_move_iterator(data.begin());
0201 auto end = std::make_move_iterator(data.end());
0202
0203 if (exe.empty())
0204 {
0205 exe = *itr;
0206 itr++;
0207 }
0208 args.insert(args.end(), itr, end);
0209 }
0210
0211 void operator()(const std::vector<string_type> & data)
0212 {
0213 if (data.empty())
0214 return;
0215
0216 auto itr = data.begin();
0217 auto end = data.end();
0218
0219 if (exe.empty())
0220 {
0221 exe = *itr;
0222 itr++;
0223 }
0224 args.insert(args.end(), itr, end);
0225 }
0226 void operator()(exe_setter_<Char> && data)
0227 {
0228 not_cmd = true;
0229 exe = std::move(data.exe_);
0230 }
0231 void operator()(const exe_setter_<Char> & data)
0232 {
0233 not_cmd = true;
0234 exe = data.exe_;
0235 }
0236 void operator()(arg_setter_<Char, false> && data)
0237 {
0238 args.assign(
0239 std::make_move_iterator(data._args.begin()),
0240 std::make_move_iterator(data._args.end()));
0241 }
0242 void operator()(arg_setter_<Char, true> && data)
0243 {
0244 args.insert(args.end(),
0245 std::make_move_iterator(data._args.begin()),
0246 std::make_move_iterator(data._args.end()));
0247 }
0248 void operator()(const arg_setter_<Char, false> & data)
0249 {
0250 args.assign(data._args.begin(), data._args.end());
0251 }
0252 void operator()(const arg_setter_<Char, true> & data)
0253 {
0254 args.insert(args.end(), data._args.begin(), data._args.end());
0255 }
0256
0257 api::exe_cmd_init<Char> get_initializer()
0258 {
0259 if (not_cmd || !args.empty())
0260 {
0261 if (shell)
0262 return api::exe_cmd_init<Char>::exe_args_shell(std::move(exe), std::move(args));
0263 else
0264 return api::exe_cmd_init<Char>::exe_args(std::move(exe), std::move(args));
0265 }
0266 else
0267 if (shell)
0268 return api::exe_cmd_init<Char>::cmd_shell(std::move(exe));
0269 else
0270 return api::exe_cmd_init<Char>::cmd(std::move(exe));
0271
0272 }
0273 typedef api::exe_cmd_init<Char> result_type;
0274 };
0275
0276 template<>
0277 struct initializer_builder<cmd_or_exe_tag<char>>
0278 {
0279 typedef exe_builder<char> type;
0280 };
0281
0282 template<>
0283 struct initializer_builder<cmd_or_exe_tag<wchar_t>>
0284 {
0285 typedef exe_builder<wchar_t> type;
0286 };
0287
0288 }}}
0289
0290
0291
0292 #endif