diff --git a/include/boost/nowide/args.hpp b/include/boost/nowide/args.hpp index 514c0a7..feb436d 100644 --- a/include/boost/nowide/args.hpp +++ b/include/boost/nowide/args.hpp @@ -9,10 +9,11 @@ #define BOOST_NOWIDE_ARGS_HPP_INCLUDED #include +#ifdef BOOST_WINDOWS #include #include -#ifdef BOOST_WINDOWS #include +#include #endif namespace boost { @@ -32,18 +33,21 @@ namespace nowide { /// Microsoft Windows. /// /// The class uses \c GetCommandLineW(), \c CommandLineToArgvW() and \c GetEnvironmentStringsW() - /// in order to obtain the information. It does not relates to actual values of argc,argv and env + /// in order to obtain the information. It does not relate to actual values of argc,argv and env /// under Windows. /// /// It restores the original values in its destructor /// + /// If any of the system calls fails, an exception of type std::runtime_error will be thrown + /// and argc, argv, env remain unchanged. + /// /// \note the class owns the memory of the newly allocated strings /// class args { public: /// - /// Fix command line agruments + /// Fix command line arguments /// args(int &argc,char **&argv) : old_argc_(argc), @@ -56,18 +60,18 @@ namespace nowide { fix_args(argc,argv); } /// - /// Fix command line agruments and environment + /// Fix command line arguments and environment /// - args(int &argc,char **&argv,char **&en) : + args(int &argc,char **&argv,char **&env) : old_argc_(argc), old_argv_(argv), - old_env_(en), + old_env_(env), old_argc_ptr_(&argc), old_argv_ptr_(&argv), - old_env_ptr_(&en) + old_env_ptr_(&env) { fix_args(argc,argv); - fix_env(en); + fix_env(env); } /// /// Restore original argc,argv,env values, if changed @@ -82,59 +86,59 @@ namespace nowide { *old_env_ptr_ = old_env_; } private: + class wargv_ptr + { + wchar_t **p; + int argc; + wargv_ptr(const wargv_ptr &); // Non-copyable + public: + explicit wargv_ptr(const wchar_t *cmd_line) : p(CommandLineToArgvW(GetCommandLineW(), &argc)) {} + ~wargv_ptr() { if(p) LocalFree(p); } + int size() const { return argc; } + operator bool() const { return p != NULL; } + const wchar_t* operator[](size_t i) const { return p[i]; } + }; + class wenv_ptr + { + wchar_t *p; + wenv_ptr(const wenv_ptr &); // Non-copyable + public: + wenv_ptr() : p(GetEnvironmentStringsW()) {} + ~wenv_ptr() { if(p) FreeEnvironmentStringsW(p); } + operator const wchar_t*() const { return p; } + }; + void fix_args(int &argc,char **&argv) { - int wargc; - wchar_t **wargv = CommandLineToArgvW(GetCommandLineW(),&wargc); - if(!wargv) { - argc = 0; - static char *dummy = 0; - argv = &dummy; - return; - } - try{ - args_.resize(wargc+1,0); - arg_values_.resize(wargc); - for(int i=0;i args_;