cmd.hpp 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. #ifndef BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
  6. #define BOOST_PROCESS_DETAIL_POSIX_CMD_HPP_
  7. #include <boost/process/v1/detail/config.hpp>
  8. #include <boost/process/v1/detail/posix/handler.hpp>
  9. #include <string>
  10. #include <vector>
  11. namespace boost
  12. {
  13. namespace process
  14. {
  15. BOOST_PROCESS_V1_INLINE namespace v1
  16. {
  17. namespace detail
  18. {
  19. namespace posix
  20. {
  21. template<typename Char>
  22. inline std::vector<std::basic_string<Char>> build_cmd(const std::basic_string<Char> & value)
  23. {
  24. std::vector<std::basic_string<Char>> ret;
  25. bool in_quotes = false;
  26. auto beg = value.begin();
  27. for (auto itr = value.begin(); itr != value.end(); itr++)
  28. {
  29. if (*itr == quote_sign<Char>())
  30. in_quotes = !in_quotes;
  31. if (!in_quotes && (*itr == space_sign<Char>()))
  32. {
  33. if (itr != beg)
  34. {
  35. ret.emplace_back(beg, itr);
  36. beg = itr + 1;
  37. }
  38. }
  39. }
  40. if (beg != value.end())
  41. ret.emplace_back(beg, value.end());
  42. return ret;
  43. }
  44. template<typename Char>
  45. struct cmd_setter_ : handler_base_ext
  46. {
  47. typedef Char value_type;
  48. typedef std::basic_string<value_type> string_type;
  49. cmd_setter_(string_type && cmd_line) : _cmd_line(api::build_cmd(std::move(cmd_line))) {}
  50. cmd_setter_(const string_type & cmd_line) : _cmd_line(api::build_cmd(cmd_line)) {}
  51. template <class Executor>
  52. void on_setup(Executor& exec)
  53. {
  54. exec.exe = _cmd_impl.front();
  55. exec.cmd_line = &_cmd_impl.front();
  56. exec.cmd_style = true;
  57. }
  58. string_type str() const
  59. {
  60. string_type ret;
  61. std::size_t size = 0;
  62. for (auto & cmd : _cmd_line)
  63. size += cmd.size() + 1;
  64. ret.reserve(size -1);
  65. for (auto & cmd : _cmd_line)
  66. {
  67. if (!ret.empty())
  68. ret += equal_sign<Char>();
  69. ret += cmd;
  70. }
  71. return ret;
  72. }
  73. private:
  74. static inline std::vector<Char*> make_cmd(std::vector<string_type> & args);
  75. std::vector<string_type> _cmd_line;
  76. std::vector<Char*> _cmd_impl = make_cmd(_cmd_line);
  77. };
  78. template<typename Char>
  79. std::vector<Char*> cmd_setter_<Char>::make_cmd(std::vector<std::basic_string<Char>> & args)
  80. {
  81. std::vector<Char*> vec;
  82. for (auto & v : args)
  83. vec.push_back(&v.front());
  84. vec.push_back(nullptr);
  85. return vec;
  86. }
  87. }}}}}
  88. #endif