File indexing completed on 2025-01-18 09:50:07
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_PROCESS_DETAIL_WINDOWS_BASIC_CMD_HPP_
0008 #define BOOST_PROCESS_DETAIL_WINDOWS_BASIC_CMD_HPP_
0009
0010 #include <boost/algorithm/string/trim.hpp>
0011 #include <boost/algorithm/string/replace.hpp>
0012 #include <boost/process/shell.hpp>
0013 #include <boost/process/detail/windows/handler.hpp>
0014
0015 #include <vector>
0016 #include <string>
0017 #include <iterator>
0018
0019
0020 namespace boost
0021 {
0022 namespace process
0023 {
0024 namespace detail
0025 {
0026 namespace windows
0027 {
0028
0029 inline std::string build_args(const std::string & exe, std::vector<std::string> && data)
0030 {
0031 std::string st = exe;
0032
0033
0034 if(!exe.empty())
0035 {
0036 auto it = st.find_first_of(" \"");
0037
0038 if(it != st.npos)
0039 {
0040
0041 boost::replace_all(st, "\"", "\"\"");
0042
0043
0044 st.insert(st.begin(), '"');
0045 st += '"';
0046 }
0047 }
0048
0049 for (auto & arg : data)
0050 {
0051 if(!arg.empty())
0052 {
0053 auto it = arg.find_first_of(" \"");
0054 if(it != arg.npos)
0055 {
0056
0057 boost::replace_all(arg, "\"", "\"\"");
0058
0059
0060 arg.insert(arg.begin(), '"');
0061 arg += '"';
0062 }
0063 }
0064 else
0065 {
0066 arg = "\"\"";
0067 }
0068
0069 if (!st.empty())
0070 st += ' ';
0071
0072 st += arg;
0073 }
0074 return st;
0075 }
0076
0077 inline std::wstring build_args(const std::wstring & exe, std::vector<std::wstring> && data)
0078 {
0079 std::wstring st = exe;
0080
0081
0082 if(!exe.empty())
0083 {
0084 auto it = st.find_first_of(L" \"");
0085
0086 if(it != st.npos)
0087 {
0088
0089 boost::replace_all(st, L"\"", L"\"\"");
0090
0091
0092 st.insert(st.begin(), L'"');
0093 st += L'"';
0094 }
0095 }
0096
0097 for(auto & arg : data)
0098 {
0099 if(!arg.empty())
0100 {
0101 auto it = arg.find_first_of(L" \"");
0102 if(it != arg.npos)
0103 {
0104
0105 boost::replace_all(arg, L"\"", L"\"\"");
0106
0107
0108 arg.insert(arg.begin(), L'"');
0109 arg += '"';
0110 }
0111 }
0112 else
0113 {
0114 arg = L"\"\"";
0115 }
0116
0117 if (!st.empty())
0118 st += L' ';
0119
0120 st += arg;
0121 }
0122 return st;
0123 }
0124
0125 template<typename Char>
0126 struct exe_cmd_init : handler_base_ext
0127 {
0128 using value_type = Char;
0129 using string_type = std::basic_string<value_type>;
0130
0131 static const char* c_arg(char) { return "/c";}
0132 static const wchar_t* c_arg(wchar_t) { return L"/c";}
0133
0134 exe_cmd_init(const string_type & exe, bool cmd_only = false)
0135 : exe(exe), args({}), cmd_only(cmd_only) {};
0136 exe_cmd_init(string_type && exe, bool cmd_only = false)
0137 : exe(std::move(exe)), args({}), cmd_only(cmd_only) {};
0138
0139 exe_cmd_init(string_type && exe, std::vector<string_type> && args)
0140 : exe(std::move(exe)), args(build_args(this->exe, std::move(args))), cmd_only(false) {};
0141 template <class Executor>
0142 void on_setup(Executor& exec) const
0143 {
0144
0145 if (cmd_only && args.empty())
0146 exec.cmd_line = exe.c_str();
0147 else
0148 {
0149 exec.exe = exe.c_str();
0150 exec.cmd_line = args.c_str();
0151 }
0152 }
0153 static exe_cmd_init<Char> exe_args(string_type && exe, std::vector<string_type> && args)
0154 {
0155 return exe_cmd_init<Char>(std::move(exe), std::move(args));
0156 }
0157 static exe_cmd_init<Char> cmd(string_type&& cmd)
0158 {
0159 return exe_cmd_init<Char>(std::move(cmd), true);
0160 }
0161 static exe_cmd_init<Char> exe_args_shell(string_type && exe, std::vector<string_type> && args)
0162 {
0163 std::vector<string_type> args_ = {c_arg(Char()), std::move(exe)};
0164 args_.insert(args_.end(), std::make_move_iterator(args.begin()), std::make_move_iterator(args.end()));
0165 string_type sh = get_shell(Char());
0166
0167 return exe_cmd_init<Char>(std::move(sh), std::move(args_));
0168 }
0169
0170 #ifdef BOOST_PROCESS_USE_STD_FS
0171 static std:: string get_shell(char) {return shell(). string(); }
0172 static std::wstring get_shell(wchar_t) {return shell().wstring(); }
0173 #else
0174 static std:: string get_shell(char) {return shell(). string(codecvt()); }
0175 static std::wstring get_shell(wchar_t) {return shell().wstring(codecvt());}
0176 #endif
0177
0178 static exe_cmd_init<Char> cmd_shell(string_type&& cmd)
0179 {
0180 std::vector<string_type> args = {c_arg(Char()), std::move(cmd)};
0181 string_type sh = get_shell(Char());
0182
0183 return exe_cmd_init<Char>(
0184 std::move(sh),
0185 std::move(args));
0186 }
0187 private:
0188 string_type exe;
0189 string_type args;
0190 bool cmd_only;
0191 };
0192
0193 }
0194
0195
0196
0197 }
0198 }
0199 }
0200
0201
0202
0203 #endif