Boost.Nowide
boost/nowide/args.hpp
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