aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/command_line.h72
-rw-r--r--src/common/util.cpp23
-rw-r--r--src/common/varint.h4
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) {