diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/command_line.h | 72 | ||||
-rw-r--r-- | src/common/util.cpp | 23 | ||||
-rw-r--r-- | src/common/varint.h | 4 |
3 files changed, 77 insertions, 22 deletions
diff --git a/src/common/command_line.h b/src/common/command_line.h index f67efcf86..3a869bb26 100644 --- a/src/common/command_line.h +++ b/src/common/command_line.h @@ -33,6 +33,7 @@ #include <functional> #include <iostream> #include <sstream> +#include <array> #include <type_traits> #include <boost/program_options/parsers.hpp> @@ -48,7 +49,7 @@ namespace command_line //! \return True if `str` is `is_iequal("n" || "no" || `tr("no"))`. bool is_no(const std::string& str); - template<typename T, bool required = false, bool dependent = false> + template<typename T, bool required = false, bool dependent = false, int NUM_DEPS = 1> struct arg_descriptor; template<typename T> @@ -98,6 +99,22 @@ namespace command_line bool not_use_default; }; + template<typename T, int NUM_DEPS> + struct arg_descriptor<T, false, true, NUM_DEPS> + { + typedef T value_type; + + const char* name; + const char* description; + + T default_value; + + std::array<const arg_descriptor<bool, false> *, NUM_DEPS> ref; + std::function<T(std::array<bool, NUM_DEPS>, bool, T)> depf; + + bool not_use_default; + }; + template<typename T> boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, true>& /*arg*/) { @@ -127,6 +144,28 @@ namespace command_line return semantic; } + template<typename T, int NUM_DEPS> + boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false, true, NUM_DEPS>& arg) + { + auto semantic = boost::program_options::value<T>(); + if (!arg.not_use_default) { + std::array<bool, NUM_DEPS> depval; + depval.fill(false); + std::ostringstream format; + format << arg.depf(depval, true, arg.default_value); + for (size_t i = 0; i < depval.size(); ++i) + { + depval.fill(false); + depval[i] = true; + format << ", " << arg.depf(depval, true, arg.default_value) << " if '" << arg.ref[i]->name << "'"; + } + for (size_t i = 0; i < depval.size(); ++i) + depval[i] = arg.ref[i]->default_value; + semantic->default_value(arg.depf(depval, true, arg.default_value), format.str()); + } + return semantic; + } + template<typename T> boost::program_options::typed_value<T, char>* make_semantic(const arg_descriptor<T, false>& arg, const T& def) { @@ -144,8 +183,8 @@ namespace command_line return semantic; } - template<typename T, bool required, bool dependent> - void add_arg(boost::program_options::options_description& description, const arg_descriptor<T, required, dependent>& arg, bool unique = true) + template<typename T, bool required, bool dependent, int NUM_DEPS> + void add_arg(boost::program_options::options_description& description, const arg_descriptor<T, required, dependent, NUM_DEPS>& arg, bool unique = true) { if (0 != description.find_nothrow(arg.name, false)) { @@ -214,35 +253,44 @@ namespace command_line } } - template<typename T, bool required> - bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg) + template<typename T, bool required, bool dependent, int NUM_DEPS> + typename std::enable_if<!std::is_same<T, bool>::value, bool>::type has_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required, dependent, NUM_DEPS>& arg) { auto value = vm[arg.name]; return !value.empty(); } - template<typename T, bool required, bool dependent> - bool is_arg_defaulted(const boost::program_options::variables_map& vm, const arg_descriptor<T, required, dependent>& arg) + template<typename T, bool required, bool dependent, int NUM_DEPS> + bool is_arg_defaulted(const boost::program_options::variables_map& vm, const arg_descriptor<T, required, dependent, NUM_DEPS>& arg) { return vm[arg.name].defaulted(); } - template<typename T, bool required> - T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required, true>& arg) + template<typename T> + T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, false, true>& arg) { return arg.depf(get_arg(vm, arg.ref), is_arg_defaulted(vm, arg), vm[arg.name].template as<T>()); } + template<typename T, int NUM_DEPS> + T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, false, true, NUM_DEPS>& arg) + { + std::array<bool, NUM_DEPS> depval; + for (size_t i = 0; i < depval.size(); ++i) + depval[i] = get_arg(vm, *arg.ref[i]); + return arg.depf(depval, is_arg_defaulted(vm, arg), vm[arg.name].template as<T>()); + } + template<typename T, bool required> T get_arg(const boost::program_options::variables_map& vm, const arg_descriptor<T, required>& arg) { return vm[arg.name].template as<T>(); } - template<> - inline bool has_arg<bool, false>(const boost::program_options::variables_map& vm, const arg_descriptor<bool, false>& arg) + template<bool dependent, int NUM_DEPS> + inline bool has_arg(const boost::program_options::variables_map& vm, const arg_descriptor<bool, false, dependent, NUM_DEPS>& arg) { - return get_arg<bool, false>(vm, arg); + return get_arg(vm, arg); } diff --git a/src/common/util.cpp b/src/common/util.cpp index e0f3cd655..d01da0fb7 100644 --- a/src/common/util.cpp +++ b/src/common/util.cpp @@ -435,15 +435,17 @@ std::string get_nix_version_display_string() #ifdef WIN32 std::string get_special_folder_path(int nfolder, bool iscreate) { - namespace fs = boost::filesystem; - char psz_path[MAX_PATH] = ""; + WCHAR psz_path[MAX_PATH] = L""; - if(SHGetSpecialFolderPathA(NULL, psz_path, nfolder, iscreate)) + if (SHGetSpecialFolderPathW(NULL, psz_path, nfolder, iscreate)) { - return psz_path; + int size_needed = WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), NULL, 0, NULL, NULL); + std::string folder_name(size_needed, 0); + WideCharToMultiByte(CP_UTF8, 0, psz_path, wcslen(psz_path), &folder_name[0], size_needed, NULL, NULL); + return folder_name; } - LOG_ERROR("SHGetSpecialFolderPathA() failed, could not obtain requested path."); + LOG_ERROR("SHGetSpecialFolderPathW() failed, could not obtain requested path."); return ""; } #endif @@ -501,13 +503,18 @@ std::string get_nix_version_display_string() int code; #if defined(WIN32) // Maximizing chances for success - DWORD attributes = ::GetFileAttributes(replaced_name.c_str()); + WCHAR wide_replacement_name[1000]; + MultiByteToWideChar(CP_UTF8, 0, replacement_name.c_str(), replacement_name.size() + 1, wide_replacement_name, 1000); + WCHAR wide_replaced_name[1000]; + MultiByteToWideChar(CP_UTF8, 0, replaced_name.c_str(), replaced_name.size() + 1, wide_replaced_name, 1000); + + DWORD attributes = ::GetFileAttributesW(wide_replaced_name); if (INVALID_FILE_ATTRIBUTES != attributes) { - ::SetFileAttributes(replaced_name.c_str(), attributes & (~FILE_ATTRIBUTE_READONLY)); + ::SetFileAttributesW(wide_replaced_name, attributes & (~FILE_ATTRIBUTE_READONLY)); } - bool ok = 0 != ::MoveFileEx(replacement_name.c_str(), replaced_name.c_str(), MOVEFILE_REPLACE_EXISTING); + bool ok = 0 != ::MoveFileExW(wide_replacement_name, wide_replaced_name, MOVEFILE_REPLACE_EXISTING); code = ok ? 0 : static_cast<int>(::GetLastError()); #else bool ok = 0 == std::rename(replacement_name.c_str(), replaced_name.c_str()); diff --git a/src/common/varint.h b/src/common/varint.h index 262bd1360..151d13dbf 100644 --- a/src/common/varint.h +++ b/src/common/varint.h @@ -45,7 +45,7 @@ * is as follows: Strip the msb of each byte, then from left to right, * read in what remains, placing it in reverse, into the buffer. Thus, * the following bit stream: 0xff02 would return 0x027f. 0xff turns - * into 0x7f, is placed on the beggining of the buffer, then 0x02 is + * into 0x7f, is placed on the beginning of the buffer, then 0x02 is * unchanged, since its msb is not set, and placed at the end of the * buffer. */ @@ -108,7 +108,7 @@ namespace tools { return EVARINT_REPRESENT; } - write |= static_cast<T>(byte & 0x7f) << shift; /* Does the actualy placing into write, stripping the first bit */ + write |= static_cast<T>(byte & 0x7f) << shift; /* Does the actually placing into write, stripping the first bit */ /* If there is no next */ if ((byte & 0x80) == 0) { |