File indexing completed on 2025-01-18 09:50:13
0001
0002
0003
0004
0005 #ifndef BOOST_PROCESS_V2_SHELL_HPP
0006 #define BOOST_PROCESS_V2_SHELL_HPP
0007
0008 #include <boost/core/exchange.hpp>
0009 #include <boost/process/v2/cstring_ref.hpp>
0010 #include <boost/process/v2/detail/config.hpp>
0011 #include <boost/process/v2/detail/utf8.hpp>
0012 #include <boost/process/v2/detail/throw_error.hpp>
0013 #include <boost/process/v2/environment.hpp>
0014 #include <memory>
0015 #include <string>
0016
0017 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0018
0019
0020 extern BOOST_PROCESS_V2_DECL const error_category& get_shell_category();
0021 static const error_category& shell_category = get_shell_category();
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047 struct shell
0048 {
0049 #if defined(BOOST_PROCESS_V2_WINDOWS)
0050 using char_type = wchar_t;
0051 using args_type = const wchar_t *;
0052 #else
0053 using char_type = char;
0054 using args_type = const char **;
0055 #endif
0056
0057 shell() = default;
0058
0059 template<typename Char, typename Traits>
0060 shell(basic_string_view<Char, Traits> input)
0061 : buffer_(detail::conv_string<char_type>(input.data(), input.size()))
0062 {
0063 parse_();
0064 }
0065
0066 shell(basic_cstring_ref<char_type> input) : input_(input) {parse_();}
0067 shell(basic_string_view<
0068 typename std::conditional<
0069 std::is_same<char_type, char>::value,
0070 wchar_t, char>::type> input) : buffer_(detail::conv_string<char_type>(input.data(), input.size()))
0071 {
0072 parse_();
0073 }
0074
0075 shell(const shell &) = delete;
0076 shell& operator=(const shell &) = delete;
0077
0078 shell(shell && lhs) noexcept
0079 : buffer_(std::move(lhs.buffer_)),
0080 input_(std::move(lhs.input_)),
0081 argc_(boost::exchange(lhs.argc_, 0)),
0082 argv_(boost::exchange(lhs.argv_, nullptr))
0083 #if defined(BOOST_PROCESS_V2_POSIX)
0084 , free_argv_(boost::exchange(lhs.free_argv_, nullptr))
0085 #endif
0086 {
0087 }
0088 shell& operator=(shell && lhs) noexcept
0089 {
0090 shell tmp(std::move(*this));
0091 buffer_ = std::move(lhs.buffer_);
0092 input_ = std::move(lhs.input_);
0093 argc_ = boost::exchange(lhs.argc_, 0);
0094 argv_ = boost::exchange(lhs.argv_, nullptr);
0095 #if defined(BOOST_PROCESS_V2_POSIX)
0096 free_argv_ = boost::exchange(lhs.free_argv_, nullptr);
0097 #endif
0098 return *this;
0099 }
0100
0101
0102 int argc() const { return argc_; }
0103 char_type** argv() const { return argv_; }
0104
0105 char_type** begin() const {return argv();}
0106 char_type** end() const {return argv() + argc();}
0107
0108 bool empty() const {return argc() == 0;}
0109 std::size_t size() const {return static_cast<std::size_t>(argc()); }
0110
0111 BOOST_PROCESS_V2_DECL args_type args() const;
0112 template<typename Environment = environment::current_view>
0113 filesystem::path exe(Environment && env = environment::current()) const
0114 {
0115 if (argc() == 0)
0116 return "";
0117 else
0118 return environment::find_executable(0[argv()], std::forward<Environment>(env));
0119 }
0120 BOOST_PROCESS_V2_DECL ~shell();
0121
0122 private:
0123
0124 friend struct make_cmd_shell_;
0125
0126 BOOST_PROCESS_V2_DECL void parse_();
0127
0128
0129 std::basic_string<char_type> buffer_;
0130 basic_cstring_ref<char_type> input_{buffer_};
0131
0132 int argc_ = 0;
0133 char_type ** argv_ = nullptr;
0134
0135 #if defined(BOOST_PROCESS_V2_POSIX)
0136 void(*free_argv_)(int, char **);
0137 #endif
0138
0139 };
0140
0141 BOOST_PROCESS_V2_END_NAMESPACE
0142
0143 #if defined(BOOST_PROCESS_V2_HEADER_ONLY)
0144
0145 #include <boost/process/v2/impl/shell.ipp>
0146
0147 #endif
0148
0149 #endif