Boost.Nowide
|
00001 // 00002 // Copyright (c) 2012 Artyom Beilis (Tonkikh) 00003 // 00004 // Distributed under the Boost Software License, Version 1.0. (See 00005 // accompanying file LICENSE_1_0.txt or copy at 00006 // http://www.boost.org/LICENSE_1_0.txt) 00007 // 00008 #ifndef BOOST_NOWIDE_ARGS_HPP_INCLUDED 00009 #define BOOST_NOWIDE_ARGS_HPP_INCLUDED 00010 00011 #include <boost/config.hpp> 00012 #include <boost/nowide/stackstring.hpp> 00013 #include <vector> 00014 #ifdef BOOST_WINDOWS 00015 #include <boost/nowide/windows.hpp> 00016 #endif 00017 00018 namespace boost { 00019 namespace nowide { 00020 #if !defined(BOOST_WINDOWS) && !defined(BOOST_NOWIDE_DOXYGEN) 00021 class args { 00022 public: 00023 args(int &,char **&) {} 00024 args(int &,char **&,char **&){} 00025 ~args() {} 00026 }; 00027 00028 #else 00029 00042 class args { 00043 public: 00044 00048 args(int &argc,char **&argv) : 00049 old_argc_(argc), 00050 old_argv_(argv), 00051 old_env_(0), 00052 old_argc_ptr_(&argc), 00053 old_argv_ptr_(&argv), 00054 old_env_ptr_(0) 00055 { 00056 fix_args(argc,argv); 00057 } 00061 args(int &argc,char **&argv,char **&en) : 00062 old_argc_(argc), 00063 old_argv_(argv), 00064 old_env_(en), 00065 old_argc_ptr_(&argc), 00066 old_argv_ptr_(&argv), 00067 old_env_ptr_(&en) 00068 { 00069 fix_args(argc,argv); 00070 fix_env(en); 00071 } 00075 ~args() 00076 { 00077 if(old_argc_ptr_) 00078 *old_argc_ptr_ = old_argc_; 00079 if(old_argv_ptr_) 00080 *old_argv_ptr_ = old_argv_; 00081 if(old_env_ptr_) 00082 *old_env_ptr_ = old_env_; 00083 } 00084 private: 00085 void fix_args(int &argc,char **&argv) 00086 { 00087 int wargc; 00088 wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(),&wargc); 00089 if(!wargv) { 00090 argc = 0; 00091 static char *dummy = 0; 00092 argv = &dummy; 00093 return; 00094 } 00095 try{ 00096 args_.resize(wargc+1,0); 00097 arg_values_.resize(wargc); 00098 for(int i=0;i<wargc;i++) { 00099 if(!arg_values_[i].convert(wargv[i])) { 00100 wargc = i; 00101 break; 00102 } 00103 args_[i] = arg_values_[i].c_str(); 00104 } 00105 argc = wargc; 00106 argv = &args_[0]; 00107 } 00108 catch(...) { 00109 LocalFree(wargv); 00110 throw; 00111 } 00112 LocalFree(wargv); 00113 } 00114 void fix_env(char **&en) 00115 { 00116 static char *dummy = 0; 00117 en = &dummy; 00118 wchar_t *wstrings = GetEnvironmentStringsW(); 00119 if(!wstrings) 00120 return; 00121 try { 00122 wchar_t *wstrings_end = 0; 00123 int count = 0; 00124 for(wstrings_end = wstrings;*wstrings_end;wstrings_end+=wcslen(wstrings_end)+1) 00125 count++; 00126 if(env_.convert(wstrings,wstrings_end)) { 00127 envp_.resize(count+1,0); 00128 char *p=env_.c_str(); 00129 int pos = 0; 00130 for(int i=0;i<count;i++) { 00131 if(*p!='=') 00132 envp_[pos++] = p; 00133 p+=strlen(p)+1; 00134 } 00135 en = &envp_[0]; 00136 } 00137 } 00138 catch(...) { 00139 FreeEnvironmentStringsW(wstrings); 00140 throw; 00141 } 00142 FreeEnvironmentStringsW(wstrings); 00143 00144 } 00145 00146 std::vector<char *> args_; 00147 std::vector<short_stackstring> arg_values_; 00148 stackstring env_; 00149 std::vector<char *> envp_; 00150 00151 int old_argc_; 00152 char **old_argv_; 00153 char **old_env_; 00154 00155 int *old_argc_ptr_; 00156 char ***old_argv_ptr_; 00157 char ***old_env_ptr_; 00158 }; 00159 00160 #endif 00161 00162 } // nowide 00163 } // namespace boost 00164 #endif 00165 00167 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4