Boost.Nowide
args.hpp
1//
2// Copyright (c) 2012 Artyom Beilis (Tonkikh)
3//
4// Distributed under the Boost Software License, Version 1.0.
5// https://www.boost.org/LICENSE_1_0.txt
6
7#ifndef BOOST_NOWIDE_ARGS_HPP_INCLUDED
8#define BOOST_NOWIDE_ARGS_HPP_INCLUDED
9
10#include <boost/config.hpp>
11#ifdef BOOST_WINDOWS
12#include <boost/nowide/stackstring.hpp>
13#include <boost/nowide/windows.hpp>
14#include <stdexcept>
15#include <vector>
16#endif
17
18namespace boost {
19namespace nowide {
20#if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN)
21 class args
22 {
23 public:
24 args(int&, char**&)
25 {}
26 args(int&, char**&, char**&)
27 {}
28 };
29
30#else
31
56 class args
57 {
58 public:
62 args(int& argc, char**& argv) :
63 old_argc_(argc), old_argv_(argv), old_env_(0), old_argc_ptr_(&argc), old_argv_ptr_(&argv), old_env_ptr_(0)
64 {
65 fix_args(argc, argv);
66 }
70 args(int& argc, char**& argv, char**& env) :
71 old_argc_(argc), old_argv_(argv), old_env_(env), old_argc_ptr_(&argc), old_argv_ptr_(&argv),
72 old_env_ptr_(&env)
73 {
74 fix_args(argc, argv);
75 fix_env(env);
76 }
81 {
82 if(old_argc_ptr_)
83 *old_argc_ptr_ = old_argc_;
84 if(old_argv_ptr_)
85 *old_argv_ptr_ = old_argv_;
86 if(old_env_ptr_)
87 *old_env_ptr_ = old_env_;
88 }
89
90 private:
91 class wargv_ptr
92 {
93 wchar_t** p;
94 int argc;
95
96 public:
97 wargv_ptr()
98 {
99 p = CommandLineToArgvW(GetCommandLineW(), &argc);
100 }
101 ~wargv_ptr()
102 {
103 if(p)
104 LocalFree(p);
105 }
106 wargv_ptr(const wargv_ptr&) = delete;
107 wargv_ptr& operator=(const wargv_ptr&) = delete;
108
109 int size() const
110 {
111 return argc;
112 }
113 operator bool() const
114 {
115 return p != nullptr;
116 }
117 const wchar_t* operator[](size_t i) const
118 {
119 return p[i];
120 }
121 };
122 class wenv_ptr
123 {
124 wchar_t* p;
125
126 public:
127 wenv_ptr() : p(GetEnvironmentStringsW())
128 {}
129 ~wenv_ptr()
130 {
131 if(p)
132 FreeEnvironmentStringsW(p);
133 }
134 wenv_ptr(const wenv_ptr&) = delete;
135 wenv_ptr& operator=(const wenv_ptr&) = delete;
136
137 operator const wchar_t*() const
138 {
139 return p;
140 }
141 };
142
143 void fix_args(int& argc, char**& argv)
144 {
145 const wargv_ptr wargv;
146 if(!wargv)
147 throw std::runtime_error("Could not get command line!");
148 args_.resize(wargv.size() + 1, 0);
149 arg_values_.resize(wargv.size());
150 for(int i = 0; i < wargv.size(); i++)
151 args_[i] = arg_values_[i].convert(wargv[i]);
152 argc = wargv.size();
153 argv = &args_[0];
154 }
155 void fix_env(char**& env)
156 {
157 const wenv_ptr wstrings;
158 if(!wstrings)
159 throw std::runtime_error("Could not get environment strings!");
160 const wchar_t* wstrings_end = 0;
161 int count = 0;
162 for(wstrings_end = wstrings; *wstrings_end; wstrings_end += wcslen(wstrings_end) + 1)
163 count++;
164 env_.convert(wstrings, wstrings_end);
165 envp_.resize(count + 1, 0);
166 char* p = env_.get();
167 int pos = 0;
168 for(int i = 0; i < count; i++)
169 {
170 if(*p != '=')
171 envp_[pos++] = p;
172 p += strlen(p) + 1;
173 }
174 env = &envp_[0];
175 }
176
177 std::vector<char*> args_;
178 std::vector<short_stackstring> arg_values_;
179 stackstring env_;
180 std::vector<char*> envp_;
181
182 int old_argc_;
183 char** old_argv_;
184 char** old_env_;
185
186 int* old_argc_ptr_;
187 char*** old_argv_ptr_;
188 char*** old_env_ptr_;
189 };
190
191#endif
192
193} // namespace nowide
194} // namespace boost
195#endif
args is a class that temporarily replaces standard main() function arguments with their equal,...
Definition: args.hpp:57
args(int &argc, char **&argv)
Definition: args.hpp:62
~args()
Definition: args.hpp:80
args(int &argc, char **&argv, char **&env)
Definition: args.hpp:70
output_char * convert(const input_char *input)
Definition: stackstring.hpp:91
output_char * get()
Return the converted, NULL-terminated string or NULL if no string was converted.
Definition: stackstring.hpp:126
size_t strlen(const Char *s)
Definition: convert.hpp:25
basic_stackstring< char, wchar_t, 256 > stackstring
Definition: stackstring.hpp:198