default_launcher.ipp 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. //
  2. // boost/process/v2/windows/impl/default_launcher.ipp
  3. // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. //
  5. // Copyright (c) 2022 Klemens D. Morgenstern (klemens dot morgenstern at gmx dot net)
  6. //
  7. // Distributed under the Boost Software License, Version 1.0. (See accompanying
  8. // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  9. //
  10. #ifndef BOOST_PROCESS_V2_WINDOWS_IMPL_DEFAULT_LAUNCHER_IPP
  11. #define BOOST_PROCESS_V2_WINDOWS_IMPL_DEFAULT_LAUNCHER_IPP
  12. #include <boost/process/v2/detail/config.hpp>
  13. #include <boost/process/v2/windows/default_launcher.hpp>
  14. BOOST_PROCESS_V2_BEGIN_NAMESPACE
  15. namespace windows
  16. {
  17. std::size_t default_launcher::escaped_argv_length(basic_string_view<wchar_t> ws)
  18. {
  19. if (ws.empty())
  20. return 2u; // just quotes
  21. constexpr static auto space = L' ';
  22. constexpr static auto quote = L'"';
  23. const auto has_space = ws.find(space) != basic_string_view<wchar_t>::npos;
  24. const auto quoted = (ws.front() == quote) && (ws.back() == quote);
  25. const auto needs_escape = has_space && !quoted ;
  26. if (!needs_escape)
  27. return ws.size();
  28. else
  29. return ws.size() + std::count(ws.begin(), ws.end(), quote) + 2u;
  30. }
  31. std::size_t default_launcher::escape_argv_string(wchar_t * itr, std::size_t max_size,
  32. basic_string_view<wchar_t> ws)
  33. {
  34. const auto sz = escaped_argv_length(ws);
  35. if (sz > max_size)
  36. return 0u;
  37. if (ws.empty())
  38. {
  39. itr[0] = L'"';
  40. itr[1] = L'"';
  41. return 2u;
  42. }
  43. const auto has_space = ws.find(L' ') != basic_string_view<wchar_t>::npos;
  44. const auto quoted = (ws.front() == L'"') && (ws.back() == L'"');
  45. const auto needs_escape = has_space && !quoted;
  46. if (!needs_escape)
  47. return std::copy(ws.begin(), ws.end(), itr) - itr;
  48. if (sz < (2u + ws.size()))
  49. return 0u;
  50. const auto end = itr + sz;
  51. const auto begin = itr;
  52. *(itr ++) = L'"';
  53. for (auto wc : ws)
  54. {
  55. if (wc == L'"')
  56. *(itr++) = L'\\';
  57. *(itr++) = wc;
  58. }
  59. *(itr ++) = L'"';
  60. return itr - begin;
  61. }
  62. }
  63. BOOST_PROCESS_V2_END_NAMESPACE
  64. #endif //BOOST_PROCESS_V2_WINDOWS_IMPL_DEFAULT_LAUNCHER_IPP