cmd.hpp 2.5 KB

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