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