// 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_WINDOWS_BASIC_CMD_HPP_ #define BOOST_PROCESS_DETAIL_WINDOWS_BASIC_CMD_HPP_ #include #include #include #include #include #include #include namespace boost { namespace process { namespace detail { namespace windows { inline std::string build_args(const std::string & exe, std::vector && data) { std::string st = exe; //put in quotes if it has spaces { boost::replace_all(st, "\"", "\\\""); auto it = std::find(st.begin(), st.end(), ' '); if (it != st.end())//contains spaces. { st.insert(st.begin(), '"'); st += '"'; } } 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::wstring build_args(const std::wstring & exe, std::vector && data) { std::wstring st = exe; //put in quotes if it has spaces { boost::replace_all(st, L"\"", L"\\\""); auto it = std::find(st.begin(), st.end(), L' '); if (it != st.end())//contains spaces. { st.insert(st.begin(), L'"'); st += L'"'; } } for (auto & arg : data) { boost::replace_all(arg, L"\"", L"\\\""); auto it = std::find(arg.begin(), arg.end(), L' ');//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(), L'"'); arg += L'"'; //thats the post one. } if (!st.empty())//first one does not need a preceeding space st += L' '; st += arg; } return st; } template struct exe_cmd_init : handler_base_ext { using value_type = Char; using string_type = std::basic_string; static const char* c_arg(char) { return "/c";} static const wchar_t* c_arg(wchar_t) { return L"/c";} exe_cmd_init(const string_type & exe, bool cmd_only = false) : exe(exe), args({}), cmd_only(cmd_only) {}; exe_cmd_init(string_type && exe, bool cmd_only = false) : exe(std::move(exe)), args({}), cmd_only(cmd_only) {}; exe_cmd_init(string_type && exe, std::vector && args) : exe(std::move(exe)), args(build_args(this->exe, std::move(args))), cmd_only(false) {}; template void on_setup(Executor& exec) const { if (cmd_only && args.empty()) exec.cmd_line = exe.c_str(); else { exec.exe = exe.c_str(); exec.cmd_line = args.c_str(); } } static exe_cmd_init exe_args(string_type && exe, std::vector && args) { return exe_cmd_init(std::move(exe), std::move(args)); } static exe_cmd_init cmd(string_type&& cmd) { return exe_cmd_init(std::move(cmd), true); } static exe_cmd_init exe_args_shell(string_type && exe, std::vector && args) { std::vector args_ = {c_arg(Char()), std::move(exe)}; args_.insert(args_.end(), std::make_move_iterator(args.begin()), std::make_move_iterator(args.end())); string_type sh = get_shell(Char()); return exe_cmd_init(std::move(sh), std::move(args_)); } static std:: string get_shell(char) {return shell(). string(codecvt()); } static std::wstring get_shell(wchar_t) {return shell().wstring(codecvt());} static exe_cmd_init cmd_shell(string_type&& cmd) { std::vector args = {c_arg(Char()), std::move(cmd)}; string_type sh = get_shell(Char()); return exe_cmd_init( std::move(sh), std::move(args)); } private: string_type exe; string_type args; bool cmd_only; }; } } } } #endif /* INCLUDE_BOOST_PROCESS_WINDOWS_ARGS_HPP_ */