File indexing completed on 2025-01-30 09:49:03
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_NOWIDE_ARGS_HPP_INCLUDED
0008 #define BOOST_NOWIDE_ARGS_HPP_INCLUDED
0009
0010 #include <boost/config.hpp>
0011 #ifdef BOOST_WINDOWS
0012 #include <boost/nowide/stackstring.hpp>
0013 #include <boost/nowide/windows.hpp>
0014 #include <stdexcept>
0015 #include <vector>
0016 #endif
0017
0018 namespace boost {
0019 namespace nowide {
0020 #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
0021 class args
0022 {
0023 public:
0024 args(int&, char**&)
0025 {}
0026 args(int&, char**&, char**&)
0027 {}
0028 };
0029
0030 #else
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056 class args
0057 {
0058 public:
0059
0060
0061
0062 args(int& argc, char**& argv) :
0063 old_argc_(argc), old_argv_(argv), old_env_(0), old_argc_ptr_(&argc), old_argv_ptr_(&argv), old_env_ptr_(0)
0064 {
0065 fix_args(argc, argv);
0066 }
0067
0068
0069
0070 args(int& argc, char**& argv, char**& env) :
0071 old_argc_(argc), old_argv_(argv), old_env_(env), old_argc_ptr_(&argc), old_argv_ptr_(&argv),
0072 old_env_ptr_(&env)
0073 {
0074 fix_args(argc, argv);
0075 fix_env(env);
0076 }
0077
0078
0079
0080 ~args()
0081 {
0082 if(old_argc_ptr_)
0083 *old_argc_ptr_ = old_argc_;
0084 if(old_argv_ptr_)
0085 *old_argv_ptr_ = old_argv_;
0086 if(old_env_ptr_)
0087 *old_env_ptr_ = old_env_;
0088 }
0089
0090 private:
0091 class wargv_ptr
0092 {
0093 wchar_t** p;
0094 int argc;
0095
0096 public:
0097 wargv_ptr()
0098 {
0099 p = CommandLineToArgvW(GetCommandLineW(), &argc);
0100 }
0101 ~wargv_ptr()
0102 {
0103 if(p)
0104 LocalFree(p);
0105 }
0106 wargv_ptr(const wargv_ptr&) = delete;
0107 wargv_ptr& operator=(const wargv_ptr&) = delete;
0108
0109 int size() const
0110 {
0111 return argc;
0112 }
0113 operator bool() const
0114 {
0115 return p != nullptr;
0116 }
0117 const wchar_t* operator[](size_t i) const
0118 {
0119 return p[i];
0120 }
0121 };
0122 class wenv_ptr
0123 {
0124 wchar_t* p;
0125
0126 public:
0127 wenv_ptr() : p(GetEnvironmentStringsW())
0128 {}
0129 ~wenv_ptr()
0130 {
0131 if(p)
0132 FreeEnvironmentStringsW(p);
0133 }
0134 wenv_ptr(const wenv_ptr&) = delete;
0135 wenv_ptr& operator=(const wenv_ptr&) = delete;
0136
0137 operator const wchar_t*() const
0138 {
0139 return p;
0140 }
0141 };
0142
0143 void fix_args(int& argc, char**& argv)
0144 {
0145 const wargv_ptr wargv;
0146 if(!wargv)
0147 throw std::runtime_error("Could not get command line!");
0148 args_.resize(wargv.size() + 1, 0);
0149 arg_values_.resize(wargv.size());
0150 for(int i = 0; i < wargv.size(); i++)
0151 args_[i] = arg_values_[i].convert(wargv[i]);
0152 argc = wargv.size();
0153 argv = &args_[0];
0154 }
0155 void fix_env(char**& env)
0156 {
0157 const wenv_ptr wstrings;
0158 if(!wstrings)
0159 throw std::runtime_error("Could not get environment strings!");
0160 const wchar_t* wstrings_end = 0;
0161 int count = 0;
0162 for(wstrings_end = wstrings; *wstrings_end; wstrings_end += wcslen(wstrings_end) + 1)
0163 count++;
0164 env_.convert(wstrings, wstrings_end);
0165 envp_.resize(count + 1, 0);
0166 char* p = env_.get();
0167 int pos = 0;
0168 for(int i = 0; i < count; i++)
0169 {
0170 if(*p != '=')
0171 envp_[pos++] = p;
0172 p += strlen(p) + 1;
0173 }
0174 env = &envp_[0];
0175 }
0176
0177 std::vector<char*> args_;
0178 std::vector<short_stackstring> arg_values_;
0179 stackstring env_;
0180 std::vector<char*> envp_;
0181
0182 int old_argc_;
0183 char** old_argv_;
0184 char** old_env_;
0185
0186 int* old_argc_ptr_;
0187 char*** old_argv_ptr_;
0188 char*** old_env_ptr_;
0189 };
0190
0191 #endif
0192
0193 }
0194 }
0195 #endif