mirror of
https://github.com/AxioDL/logvisor.git
synced 2025-12-09 13:37:53 +00:00
Update fmt to 8.0.0; drop support for wchar
Adds some boost-nowide headers to assist in UTF-8/16 conversion for Windows API.
This commit is contained in:
194
include/nowide/args.hpp
Normal file
194
include/nowide/args.hpp
Normal file
@@ -0,0 +1,194 @@
|
||||
//
|
||||
// Copyright (c) 2012 Artyom Beilis (Tonkikh)
|
||||
//
|
||||
// Distributed under the Boost Software License, Version 1.0. (See
|
||||
// accompanying file LICENSE or copy at
|
||||
// http://www.boost.org/LICENSE_1_0.txt)
|
||||
//
|
||||
#ifndef NOWIDE_ARGS_HPP_INCLUDED
|
||||
#define NOWIDE_ARGS_HPP_INCLUDED
|
||||
|
||||
#include <nowide/config.hpp>
|
||||
#ifdef NOWIDE_WINDOWS
|
||||
#include <nowide/stackstring.hpp>
|
||||
#include <nowide/windows.hpp>
|
||||
#include <stdexcept>
|
||||
#include <vector>
|
||||
#endif
|
||||
|
||||
namespace nowide {
|
||||
#if !defined(NOWIDE_WINDOWS) && !defined(NOWIDE_DOXYGEN)
|
||||
class args
|
||||
{
|
||||
public:
|
||||
args(int&, char**&)
|
||||
{}
|
||||
args(int&, char**&, char**&)
|
||||
{}
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
///
|
||||
/// \brief \c args is a class that temporarily replaces standard main() function arguments with their
|
||||
/// equal, but UTF-8 encoded values under Microsoft Windows for the lifetime of the instance.
|
||||
///
|
||||
/// The class uses \c GetCommandLineW(), \c CommandLineToArgvW() and \c GetEnvironmentStringsW()
|
||||
/// in order to obtain Unicode-encoded values.
|
||||
/// It does not relate to actual values of argc, argv and env under Windows.
|
||||
///
|
||||
/// It restores the original values in its destructor (usually at the end of the \c main function).
|
||||
///
|
||||
/// 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.
|
||||
/// So you need to keep it alive as long as you use the values.
|
||||
///
|
||||
/// Usage:
|
||||
/// \code
|
||||
/// int main(int argc, char** argv, char** env) {
|
||||
/// nowide::args _(argc, argv, env); // Note the _ as a "don't care" name for the instance
|
||||
/// // Use argv and env as usual, they are now UTF-8 encoded on Windows
|
||||
/// return 0; // Memory held by args is released
|
||||
/// }
|
||||
/// \endcode
|
||||
class args
|
||||
{
|
||||
public:
|
||||
///
|
||||
/// Fix command line arguments
|
||||
///
|
||||
args(int& argc, char**& argv) :
|
||||
old_argc_(argc), old_argv_(argv), old_env_(0), old_argc_ptr_(&argc), old_argv_ptr_(&argv), old_env_ptr_(0)
|
||||
{
|
||||
fix_args(argc, argv);
|
||||
}
|
||||
///
|
||||
/// Fix command line arguments and environment
|
||||
///
|
||||
args(int& argc, char**& argv, char**& env) :
|
||||
old_argc_(argc), old_argv_(argv), old_env_(env), old_argc_ptr_(&argc), old_argv_ptr_(&argv),
|
||||
old_env_ptr_(&env)
|
||||
{
|
||||
fix_args(argc, argv);
|
||||
fix_env(env);
|
||||
}
|
||||
///
|
||||
/// Restore original argc, argv, env values, if changed
|
||||
///
|
||||
~args()
|
||||
{
|
||||
if(old_argc_ptr_)
|
||||
*old_argc_ptr_ = old_argc_;
|
||||
if(old_argv_ptr_)
|
||||
*old_argv_ptr_ = old_argv_;
|
||||
if(old_env_ptr_)
|
||||
*old_env_ptr_ = old_env_;
|
||||
}
|
||||
|
||||
private:
|
||||
class wargv_ptr
|
||||
{
|
||||
wchar_t** p;
|
||||
int argc;
|
||||
|
||||
public:
|
||||
wargv_ptr()
|
||||
{
|
||||
p = CommandLineToArgvW(GetCommandLineW(), &argc);
|
||||
}
|
||||
~wargv_ptr()
|
||||
{
|
||||
if(p)
|
||||
LocalFree(p);
|
||||
}
|
||||
wargv_ptr(const wargv_ptr&) = delete;
|
||||
wargv_ptr& operator=(const wargv_ptr&) = delete;
|
||||
|
||||
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;
|
||||
|
||||
public:
|
||||
wenv_ptr() : p(GetEnvironmentStringsW())
|
||||
{}
|
||||
~wenv_ptr()
|
||||
{
|
||||
if(p)
|
||||
FreeEnvironmentStringsW(p);
|
||||
}
|
||||
wenv_ptr(const wenv_ptr&) = delete;
|
||||
wenv_ptr& operator=(const wenv_ptr&) = delete;
|
||||
|
||||
operator const wchar_t*() const
|
||||
{
|
||||
return p;
|
||||
}
|
||||
};
|
||||
|
||||
void fix_args(int& argc, char**& argv)
|
||||
{
|
||||
const wargv_ptr wargv;
|
||||
if(!wargv)
|
||||
throw std::runtime_error("Could not get command line!");
|
||||
args_.resize(wargv.size() + 1, 0);
|
||||
arg_values_.resize(wargv.size());
|
||||
for(int i = 0; i < wargv.size(); i++)
|
||||
args_[i] = arg_values_[i].convert(wargv[i]);
|
||||
argc = wargv.size();
|
||||
argv = &args_[0];
|
||||
}
|
||||
void fix_env(char**& env)
|
||||
{
|
||||
const wenv_ptr wstrings;
|
||||
if(!wstrings)
|
||||
throw std::runtime_error("Could not get environment strings!");
|
||||
const wchar_t* wstrings_end = 0;
|
||||
int count = 0;
|
||||
for(wstrings_end = wstrings; *wstrings_end; wstrings_end += wcslen(wstrings_end) + 1)
|
||||
count++;
|
||||
env_.convert(wstrings, wstrings_end);
|
||||
envp_.resize(count + 1, 0);
|
||||
char* p = env_.get();
|
||||
int pos = 0;
|
||||
for(int i = 0; i < count; i++)
|
||||
{
|
||||
if(*p != '=')
|
||||
envp_[pos++] = p;
|
||||
p += strlen(p) + 1;
|
||||
}
|
||||
env = &envp_[0];
|
||||
}
|
||||
|
||||
std::vector<char*> args_;
|
||||
std::vector<short_stackstring> arg_values_;
|
||||
stackstring env_;
|
||||
std::vector<char*> envp_;
|
||||
|
||||
int old_argc_;
|
||||
char** old_argv_;
|
||||
char** old_env_;
|
||||
|
||||
int* old_argc_ptr_;
|
||||
char*** old_argv_ptr_;
|
||||
char*** old_env_ptr_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
} // namespace nowide
|
||||
#endif
|
||||
Reference in New Issue
Block a user