Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:50:11

0001 // Copyright (c) 2022 Klemens D. Morgenstern
0002 //
0003 // Distributed under the Boost Software License, Version 1.0. (See accompanying
0004 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
0005 #ifndef BOOST_PROCESS_V2_IMPL_SHELL_IPP
0006 #define BOOST_PROCESS_V2_IMPL_SHELL_IPP
0007 
0008 #include <boost/process/v2/detail/config.hpp>
0009 #include <boost/process/v2/detail/last_error.hpp>
0010 #include <boost/process/v2/detail/throw_error.hpp>
0011 #include <boost/process/v2/detail/config.hpp>
0012 #include <boost/process/v2/error.hpp>
0013 #include <boost/process/v2/shell.hpp>
0014 
0015 #if defined(BOOST_PROCESS_V2_WINDOWS)
0016 #include <shellapi.h>
0017 #else
0018 #include <wordexp.h>
0019 #endif
0020 
0021 BOOST_PROCESS_V2_BEGIN_NAMESPACE
0022 
0023 #if defined(BOOST_PROCESS_V2_WINDOWS)
0024 BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
0025 {
0026     return system_category();
0027 }
0028 #else
0029 
0030 struct shell_category_t final : public error_category
0031 {
0032     shell_category_t() : error_category(0xDAF1u) {}
0033 
0034     const char* name() const noexcept
0035     {
0036         return "process.v2.utf8";
0037     }
0038     std::string message(int value) const
0039     {
0040         switch (value)
0041         {
0042         case WRDE_BADCHAR:
0043             return "Illegal occurrence of newline or one of |, &, ;, <, >, (, ), {, }.";
0044         case WRDE_BADVAL:
0045             return "An undefined shell variable was referenced, and the WRDE_UNDEF flag told us to consider this an error.";
0046         case WRDE_CMDSUB:
0047             return "Command substitution occurred, and the WRDE_NOCMD flag told us to consider this an error.";
0048         case WRDE_NOSPACE:
0049             return "Out of memory.";
0050         case WRDE_SYNTAX:
0051             return "Shell syntax error, such as unbalanced parentheses or unmatched quotes.";
0052         default:
0053             return "process.v2.wordexp error";
0054         }
0055     }
0056 };
0057 
0058 BOOST_PROCESS_V2_DECL const error_category& get_shell_category()
0059 {
0060     static shell_category_t instance;
0061     return instance;
0062 }
0063 
0064 #endif
0065 
0066 #if defined (BOOST_PROCESS_V2_WINDOWS)
0067 
0068 void shell::parse_()
0069 {
0070     argv_ = ::CommandLineToArgvW(input_.c_str(), &argc_);
0071     if (argv_ == nullptr)
0072     {
0073         error_code ec;
0074         BOOST_PROCESS_V2_ASSIGN_LAST_ERROR(ec);
0075         throw system_error(ec, "shell::parse");
0076     }
0077 }
0078 
0079 shell::~shell()
0080 {
0081     if (argv_ != nullptr)
0082         LocalFree(argv_);
0083 }
0084 
0085 auto shell::args() const-> args_type
0086 {
0087     return input_.c_str();
0088 }
0089 
0090 #else
0091 
0092 void shell::parse_()
0093 {
0094     wordexp_t we{};
0095     auto cd = wordexp(input_.c_str(), &we, WRDE_NOCMD);
0096 
0097     if (cd != 0)
0098         detail::throw_error(error_code(cd, get_shell_category()), "shell::parse");
0099     else
0100     {
0101         argc_ = static_cast<int>(we.we_wordc);
0102         argv_ = we.we_wordv;
0103     }
0104 
0105     free_argv_ = +[](int argc, char ** argv)
0106     {
0107         wordexp_t we{
0108                 .we_wordc = static_cast<std::size_t>(argc),
0109                 .we_wordv = argv,
0110                 .we_offs = 0
0111         };
0112         wordfree(&we);
0113     };
0114 }
0115 
0116 shell::~shell()
0117 {
0118     if (argv_ != nullptr && free_argv_ != nullptr)
0119         free_argv_(argc_, argv_);
0120 }
0121 
0122 auto shell::args() const -> args_type
0123 {
0124     if (argc() == 0)
0125     {
0126         static const char * helper = nullptr;
0127         return &helper;
0128     }
0129     else
0130         return const_cast<const char**>(argv());
0131 }
0132 
0133 #endif
0134 
0135 BOOST_PROCESS_V2_END_NAMESPACE
0136 
0137 #endif //BOOST_PROCESS_V2_IMPL_SHELL_IPP