diff options
Diffstat (limited to 'extern/gflags')
-rw-r--r-- | extern/gflags/CMakeLists.txt | 2 | ||||
-rw-r--r-- | extern/gflags/README.blender | 16 | ||||
-rw-r--r-- | extern/gflags/src/gflags.cc | 316 | ||||
-rw-r--r-- | extern/gflags/src/gflags/config.h (renamed from extern/gflags/src/config.h) | 17 | ||||
-rw-r--r-- | extern/gflags/src/gflags/gflags.h | 49 | ||||
-rw-r--r-- | extern/gflags/src/gflags/gflags_declare.h | 20 | ||||
-rw-r--r-- | extern/gflags/src/gflags/gflags_gflags.h | 1 | ||||
-rw-r--r-- | extern/gflags/src/gflags_completions.cc | 15 | ||||
-rw-r--r-- | extern/gflags/src/gflags_reporting.cc | 7 | ||||
-rw-r--r-- | extern/gflags/src/mutex.h | 6 | ||||
-rw-r--r-- | extern/gflags/src/util.h | 1 | ||||
-rw-r--r-- | extern/gflags/src/windows_port.h | 6 |
12 files changed, 295 insertions, 161 deletions
diff --git a/extern/gflags/CMakeLists.txt b/extern/gflags/CMakeLists.txt index 8977fcca457..a473e6ffb40 100644 --- a/extern/gflags/CMakeLists.txt +++ b/extern/gflags/CMakeLists.txt @@ -35,7 +35,7 @@ set(SRC src/gflags_completions.cc src/gflags_reporting.cc - src/config.h + src/gflags/config.h src/gflags/gflags_completions.h src/gflags/gflags_declare.h src/gflags/gflags_gflags.h diff --git a/extern/gflags/README.blender b/extern/gflags/README.blender index b48d4d5d110..1f6f0111776 100644 --- a/extern/gflags/README.blender +++ b/extern/gflags/README.blender @@ -1,25 +1,23 @@ Project: Google Flags URL: https://github.com/gflags/gflags License: New BSD -Upstream version: 2.2.0 (9db82895) +Upstream version: 2.2.1 (46f73f88b18) Local modifications: -- Flattened the tree and only included files needed for libmv. +- Flattened the tree and only included files needed for Blender. - config.h was originally generated on linux machine with some further tweaks: * OS_WINDOWS need to be conditinally defined from inside #ifdef WIN32 - * Same applies yo HAVE_SHLWAPI_H + * Same applies to HAVE_SHLWAPI_H * Disabeld HAVE_FNMATCH_H - -- Removed attribute(unused) from FlagSaver. + * Forced disabled GFLAGS_IS_A_DLL - Applied some modifications from fork https://github.com/Nazg-Gul/gflags.git (see https://github.com/gflags/gflags/pull/129) -- Avoid attempt of acquiring mutex lock in FlagRegistry::GlobalRegistry when - doing static flags initialization. See d81dd2d in Blender repository. - - Made `google::{anonymous}::FlagValue::ValueSize() const` inlined, so it does - not trigger strict compiler warning.
\ No newline at end of file + not trigger strict compiler warning. + +- Did the same for CommandLineFlagParser::ValidateFlags(). diff --git a/extern/gflags/src/gflags.cc b/extern/gflags/src/gflags.cc index 6dcc5170bcc..60965d3d201 100644 --- a/extern/gflags/src/gflags.cc +++ b/extern/gflags/src/gflags.cc @@ -88,7 +88,7 @@ // are, similarly, mostly hooks into the functionality described above. #include "config.h" -#include "gflags.h" +#include "gflags/gflags.h" #include <assert.h> #include <ctype.h> @@ -96,6 +96,7 @@ #if defined(HAVE_FNMATCH_H) # include <fnmatch.h> #elif defined(HAVE_SHLWAPI_H) +# define NO_SHLWAPI_ISOS # include <shlwapi.h> #endif #include <stdarg.h> // For va_list and related operations @@ -170,12 +171,10 @@ enum DieWhenReporting { DIE, DO_NOT_DIE }; // Report Error and exit if requested. static void ReportError(DieWhenReporting should_die, const char* format, ...) { - char error_message[255]; va_list ap; va_start(ap, format); - vsnprintf(error_message, sizeof(error_message), format, ap); + vfprintf(stderr, format, ap); va_end(ap); - fprintf(stderr, "%s", error_message); fflush(stderr); // should be unnecessary, but cygwin's rxvt buffers stderr if (should_die == DIE) gflags_exitfunc(1); } @@ -191,29 +190,37 @@ static void ReportError(DieWhenReporting should_die, const char* format, ...) { class CommandLineFlag; class FlagValue { public: - FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value); + enum ValueType { + FV_BOOL = 0, + FV_INT32 = 1, + FV_UINT32 = 2, + FV_INT64 = 3, + FV_UINT64 = 4, + FV_DOUBLE = 5, + FV_STRING = 6, + FV_MAX_INDEX = 6, + }; + + template <typename FlagType> + FlagValue(FlagType* valbuf, bool transfer_ownership_of_value); ~FlagValue(); bool ParseFrom(const char* spec); string ToString() const; + ValueType Type() const { return static_cast<ValueType>(type_); } + private: friend class CommandLineFlag; // for many things, including Validate() friend class GFLAGS_NAMESPACE::FlagSaverImpl; // calls New() friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map - template <typename T> friend T GetFromEnv(const char*, const char*, T); + template <typename T> friend T GetFromEnv(const char*, T); friend bool TryParseLocked(const CommandLineFlag*, FlagValue*, const char*, string*); // for New(), CopyFrom() - enum ValueType { - FV_BOOL = 0, - FV_INT32 = 1, - FV_INT64 = 2, - FV_UINT64 = 3, - FV_DOUBLE = 4, - FV_STRING = 5, - FV_MAX_INDEX = 5, - }; + template <typename FlagType> + struct FlagValueTraits; + const char* TypeName() const; bool Equal(const FlagValue& x) const; FlagValue* New() const; // creates a new one with default value @@ -226,14 +233,33 @@ class FlagValue { // (*validate_fn)(bool) for a bool flag). bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const; - void* value_buffer_; // points to the buffer holding our data - int8 type_; // how to interpret value_ - bool owns_value_; // whether to free value on destruct + void* const value_buffer_; // points to the buffer holding our data + const int8 type_; // how to interpret value_ + const bool owns_value_; // whether to free value on destruct FlagValue(const FlagValue&); // no copying! void operator=(const FlagValue&); }; +// Map the given C++ type to a value of the ValueType enum at compile time. +#define DEFINE_FLAG_TRAITS(type, value) \ + template <> \ + struct FlagValue::FlagValueTraits<type> { \ + static const ValueType kValueType = value; \ + } + +// Define full template specializations of the FlagValueTraits template +// for all supported flag types. +DEFINE_FLAG_TRAITS(bool, FV_BOOL); +DEFINE_FLAG_TRAITS(int32, FV_INT32); +DEFINE_FLAG_TRAITS(uint32, FV_UINT32); +DEFINE_FLAG_TRAITS(int64, FV_INT64); +DEFINE_FLAG_TRAITS(uint64, FV_UINT64); +DEFINE_FLAG_TRAITS(double, FV_DOUBLE); +DEFINE_FLAG_TRAITS(std::string, FV_STRING); + +#undef DEFINE_FLAG_TRAITS + // This could be a templated method of FlagValue, but doing so adds to the // size of the .o. Since there's no type-safety here anyway, macro is ok. @@ -241,16 +267,12 @@ class FlagValue { #define OTHER_VALUE_AS(fv, type) *reinterpret_cast<type*>(fv.value_buffer_) #define SET_VALUE_AS(type, value) VALUE_AS(type) = (value) -FlagValue::FlagValue(void* valbuf, const char* type, +template <typename FlagType> +FlagValue::FlagValue(FlagType* valbuf, bool transfer_ownership_of_value) : value_buffer_(valbuf), + type_(FlagValueTraits<FlagType>::kValueType), owns_value_(transfer_ownership_of_value) { - for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) { - if (!strcmp(type, TypeName())) { - break; - } - } - assert(type_ <= FV_MAX_INDEX); // Unknown typename } FlagValue::~FlagValue() { @@ -260,6 +282,7 @@ FlagValue::~FlagValue() { switch (type_) { case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break; case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break; + case FV_UINT32: delete reinterpret_cast<uint32*>(value_buffer_); break; case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break; case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break; case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break; @@ -308,6 +331,16 @@ bool FlagValue::ParseFrom(const char* value) { SET_VALUE_AS(int32, static_cast<int32>(r)); return true; } + case FV_UINT32: { + while (*value == ' ') value++; + if (*value == '-') return false; // negative number + const uint64 r = strtou64(value, &end, base); + if (errno || end != value + strlen(value)) return false; // bad parse + if (static_cast<uint32>(r) != r) // worked, but number out of range + return false; + SET_VALUE_AS(uint32, static_cast<uint32>(r)); + return true; + } case FV_INT64: { const int64 r = strto64(value, &end, base); if (errno || end != value + strlen(value)) return false; // bad parse @@ -343,6 +376,9 @@ string FlagValue::ToString() const { case FV_INT32: snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32)); return intbuf; + case FV_UINT32: + snprintf(intbuf, sizeof(intbuf), "%" PRIu32, VALUE_AS(uint32)); + return intbuf; case FV_INT64: snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64)); return intbuf; @@ -369,6 +405,9 @@ bool FlagValue::Validate(const char* flagname, case FV_INT32: return reinterpret_cast<bool (*)(const char*, int32)>( validate_fn_proto)(flagname, VALUE_AS(int32)); + case FV_UINT32: + return reinterpret_cast<bool (*)(const char*, uint32)>( + validate_fn_proto)(flagname, VALUE_AS(uint32)); case FV_INT64: return reinterpret_cast<bool (*)(const char*, int64)>( validate_fn_proto)(flagname, VALUE_AS(int64)); @@ -391,6 +430,7 @@ const char* FlagValue::TypeName() const { static const char types[] = "bool\0xx" "int32\0x" + "uint32\0" "int64\0x" "uint64\0" "double\0" @@ -409,6 +449,7 @@ bool FlagValue::Equal(const FlagValue& x) const { switch (type_) { case FV_BOOL: return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool); case FV_INT32: return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32); + case FV_UINT32: return VALUE_AS(uint32) == OTHER_VALUE_AS(x, uint32); case FV_INT64: return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64); case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64); case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double); @@ -418,14 +459,14 @@ bool FlagValue::Equal(const FlagValue& x) const { } FlagValue* FlagValue::New() const { - const char *type = TypeName(); switch (type_) { - case FV_BOOL: return new FlagValue(new bool(false), type, true); - case FV_INT32: return new FlagValue(new int32(0), type, true); - case FV_INT64: return new FlagValue(new int64(0), type, true); - case FV_UINT64: return new FlagValue(new uint64(0), type, true); - case FV_DOUBLE: return new FlagValue(new double(0.0), type, true); - case FV_STRING: return new FlagValue(new string, type, true); + case FV_BOOL: return new FlagValue(new bool(false), true); + case FV_INT32: return new FlagValue(new int32(0), true); + case FV_UINT32: return new FlagValue(new uint32(0), true); + case FV_INT64: return new FlagValue(new int64(0), true); + case FV_UINT64: return new FlagValue(new uint64(0), true); + case FV_DOUBLE: return new FlagValue(new double(0.0), true); + case FV_STRING: return new FlagValue(new string, true); default: assert(false); return NULL; // unknown type } } @@ -435,6 +476,7 @@ void FlagValue::CopyFrom(const FlagValue& x) { switch (type_) { case FV_BOOL: SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool)); break; case FV_INT32: SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32)); break; + case FV_UINT32: SET_VALUE_AS(uint32, OTHER_VALUE_AS(x, uint32)); break; case FV_INT64: SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64)); break; case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64)); break; case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double)); break; @@ -451,6 +493,7 @@ inline int FlagValue::ValueSize() const { static const uint8 valuesize[] = { sizeof(bool), sizeof(int32), + sizeof(uint32), sizeof(int64), sizeof(uint64), sizeof(double), @@ -487,11 +530,14 @@ class CommandLineFlag { ValidateFnProto validate_function() const { return validate_fn_proto_; } const void* flag_ptr() const { return current_->value_buffer_; } + FlagValue::ValueType Type() const { return defvalue_->Type(); } + void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result); // If validate_fn_proto_ is non-NULL, calls it on value, returns result. bool Validate(const FlagValue& value) const; bool ValidateCurrent() const { return Validate(*current_); } + bool Modified() const { return modified_; } private: // for SetFlagLocked() and setting flags_by_ptr_ @@ -545,7 +591,7 @@ const char* CommandLineFlag::CleanFileName() const { const char* clean_name = filename() + strlen(filename()) - 1; while ( clean_name > filename() ) { if (*clean_name == PATH_SEPARATOR) { - if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) { + if (sizeof(kRootDir) > 1 && strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) { clean_name += sizeof(kRootDir)-1; // past root-dir break; } @@ -664,7 +710,7 @@ class FlagRegistry { private: friend class GFLAGS_NAMESPACE::FlagSaverImpl; // reads all the flags in order to copy them - friend class CommandLineFlagParser; // for ValidateAllFlags + friend class CommandLineFlagParser; // for ValidateUnmodifiedFlags friend void GFLAGS_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*); // The map from name to flag, for FindFlagLocked(). @@ -680,7 +726,6 @@ class FlagRegistry { static FlagRegistry* global_registry_; // a singleton registry Mutex lock_; - static Mutex global_registry_lock_; static void InitGlobalRegistry(); @@ -725,7 +770,12 @@ void FlagRegistry::RegisterFlag(CommandLineFlag* flag) { CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) { FlagConstIterator i = flags_.find(name); if (i == flags_.end()) { - return NULL; + // If the name has dashes in it, try again after replacing with + // underscores. + if (strchr(name, '-') == NULL) return NULL; + string name_rep = name; + std::replace(name_rep.begin(), name_rep.end(), '-', '_'); + return FindFlagLocked(name_rep.c_str()); } else { return i->second; } @@ -777,7 +827,7 @@ CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg, kError, key->c_str()); return NULL; } - if (strcmp(flag->type_name(), "bool") != 0) { + if (flag->Type() != FlagValue::FV_BOOL) { // 'x' exists but is not boolean, so we're not in the exception case. *error_message = StringPrintf( "%sboolean value (%s) specified for %s command line flag\n", @@ -791,7 +841,7 @@ CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg, } // Assign a value if this is a boolean flag - if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) { + if (*v == NULL && flag->Type() == FlagValue::FV_BOOL) { *v = "1"; // the --nox case was already handled, so this is the --x case } @@ -878,18 +928,12 @@ bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag, // Get the singleton FlagRegistry object FlagRegistry* FlagRegistry::global_registry_ = NULL; -Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED); FlagRegistry* FlagRegistry::GlobalRegistry() { - if (GetArgvSum() != 0) { - MutexLock acquire_lock(&global_registry_lock_); - if (!global_registry_) { - global_registry_ = new FlagRegistry; - } - } else { - if (!global_registry_) { - global_registry_ = new FlagRegistry; - } + static Mutex lock(Mutex::LINKER_INITIALIZED); + MutexLock acquire_lock(&lock); + if (!global_registry_) { + global_registry_ = new FlagRegistry; } return global_registry_; } @@ -926,8 +970,10 @@ class CommandLineFlagParser { // In gflags_reporting.cc:HandleCommandLineHelpFlags(). // Stage 3: validate all the commandline flags that have validators - // registered. + // registered and were not set/modified by ParseNewCommandLineFlags. + void ValidateFlags(bool all); void ValidateAllFlags(); + void ValidateUnmodifiedFlags(); // Stage 4: report any errors and return true if any were found. bool ReportErrors(); @@ -1014,9 +1060,6 @@ static string ReadFileIntoString(const char* filename) { uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags) { - const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR); // nix path - program_name = (program_name == NULL ? (*argv)[0] : program_name+1); - int first_nonopt = *argc; // for non-options moved to the end registry_->Lock(); @@ -1056,7 +1099,7 @@ uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv, if (value == NULL) { // Boolean options are always assigned a value by SplitArgumentLocked() - assert(strcmp(flag->type_name(), "bool") != 0); + assert(flag->Type() != FlagValue::FV_BOOL); if (i+1 >= first_nonopt) { // This flag needs a value, but there is nothing available error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'" @@ -1081,7 +1124,7 @@ uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv, // "-lat -30.5" would trigger the warning. The common cases we // want to solve talk about true and false as values. if (value[0] == '-' - && strcmp(flag->type_name(), "string") == 0 + && flag->Type() == FlagValue::FV_STRING && (strstr(flag->help(), "true") || strstr(flag->help(), "false"))) { LOG(WARNING) << "Did you really mean to set flag '" @@ -1146,8 +1189,8 @@ string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval, } const string envname = string("FLAGS_") + string(flagname); - string envval; - if (!SafeGetEnv(envname.c_str(), envval)) { + string envval; + if (!SafeGetEnv(envname.c_str(), envval)) { if (errors_are_fatal) { error_flags_[flagname] = (string(kError) + envname + " not found in environment\n"); @@ -1193,23 +1236,35 @@ string CommandLineFlagParser::ProcessSingleOptionLocked( return msg; } -void CommandLineFlagParser::ValidateAllFlags() { +void CommandLineFlagParser::ValidateFlags(bool all) { FlagRegistryLock frl(registry_); for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin(); i != registry_->flags_.end(); ++i) { - if (!i->second->ValidateCurrent()) { + if ((all || !i->second->Modified()) && !i->second->ValidateCurrent()) { // only set a message if one isn't already there. (If there's // an error message, our job is done, even if it's not exactly // the same error.) - if (error_flags_[i->second->name()].empty()) + if (error_flags_[i->second->name()].empty()) { error_flags_[i->second->name()] = string(kError) + "--" + i->second->name() + - " must be set on the commandline" - " (default value fails validation)\n"; + " must be set on the commandline"; + if (!i->second->Modified()) { + error_flags_[i->second->name()] += " (default value fails validation)"; + } + error_flags_[i->second->name()] += "\n"; + } } } } +inline void CommandLineFlagParser::ValidateAllFlags() { + ValidateFlags(true); +} + +void CommandLineFlagParser::ValidateUnmodifiedFlags() { + ValidateFlags(false); +} + bool CommandLineFlagParser::ReportErrors() { // error_flags_ indicates errors we saw while parsing. // But we ignore undefined-names if ok'ed by --undef_ok @@ -1261,7 +1316,11 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked( for (; line_end; flagfile_contents = line_end + 1) { while (*flagfile_contents && isspace(*flagfile_contents)) ++flagfile_contents; - line_end = strchr(flagfile_contents, '\n'); + // Windows uses "\r\n" + line_end = strchr(flagfile_contents, '\r'); + if (line_end == NULL) + line_end = strchr(flagfile_contents, '\n'); + size_t len = line_end ? line_end - flagfile_contents : strlen(flagfile_contents); string line(flagfile_contents, len); @@ -1341,14 +1400,14 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked( // -------------------------------------------------------------------- template<typename T> -T GetFromEnv(const char *varname, const char* type, T dflt) { +T GetFromEnv(const char *varname, T dflt) { std::string valstr; if (SafeGetEnv(varname, valstr)) { - FlagValue ifv(new T, type, true); + FlagValue ifv(new T, true); if (!ifv.ParseFrom(valstr.c_str())) { ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n", varname, valstr.c_str()); - } + } return OTHER_VALUE_AS(ifv, T); } else return dflt; } @@ -1395,22 +1454,48 @@ bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) { // values in a global destructor. // -------------------------------------------------------------------- -FlagRegisterer::FlagRegisterer(const char* name, const char* type, - const char* help, const char* filename, - void* current_storage, void* defvalue_storage) { +namespace { +void RegisterCommandLineFlag(const char* name, + const char* help, + const char* filename, + FlagValue* current, + FlagValue* defvalue) { if (help == NULL) help = ""; - // FlagValue expects the type-name to not include any namespace - // components, so we get rid of those, if any. - if (strchr(type, ':')) - type = strrchr(type, ':') + 1; - FlagValue* current = new FlagValue(current_storage, type, false); - FlagValue* defvalue = new FlagValue(defvalue_storage, type, false); // Importantly, flag_ will never be deleted, so storage is always good. - CommandLineFlag* flag = new CommandLineFlag(name, help, filename, - current, defvalue); - FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry + CommandLineFlag* flag = + new CommandLineFlag(name, help, filename, current, defvalue); + FlagRegistry::GlobalRegistry()->RegisterFlag(flag); // default registry } +} + +template <typename FlagType> +FlagRegisterer::FlagRegisterer(const char* name, + const char* help, + const char* filename, + FlagType* current_storage, + FlagType* defvalue_storage) { + FlagValue* const current = new FlagValue(current_storage, false); + FlagValue* const defvalue = new FlagValue(defvalue_storage, false); + RegisterCommandLineFlag(name, help, filename, current, defvalue); +} + +// Force compiler to generate code for the given template specialization. +#define INSTANTIATE_FLAG_REGISTERER_CTOR(type) \ + template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \ + const char* name, const char* help, const char* filename, \ + type* current_storage, type* defvalue_storage) + +// Do this for all supported flag types. +INSTANTIATE_FLAG_REGISTERER_CTOR(bool); +INSTANTIATE_FLAG_REGISTERER_CTOR(int32); +INSTANTIATE_FLAG_REGISTERER_CTOR(uint32); +INSTANTIATE_FLAG_REGISTERER_CTOR(int64); +INSTANTIATE_FLAG_REGISTERER_CTOR(uint64); +INSTANTIATE_FLAG_REGISTERER_CTOR(double); +INSTANTIATE_FLAG_REGISTERER_CTOR(std::string); + +#undef INSTANTIATE_FLAG_REGISTERER_CTOR // -------------------------------------------------------------------- // GetAllFlags() @@ -1460,65 +1545,58 @@ void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) { // These values are not protected by a Mutex because they are normally // set only once during program startup. -static const char* argv0 = "UNKNOWN"; // just the program name -static const char* cmdline = ""; // the entire command-line +static string argv0("UNKNOWN"); // just the program name +static string cmdline; // the entire command-line +static string program_usage; static vector<string> argvs; static uint32 argv_sum = 0; -static const char* program_usage = NULL; void SetArgv(int argc, const char** argv) { static bool called_set_argv = false; - if (called_set_argv) // we already have an argv for you - return; - + if (called_set_argv) return; called_set_argv = true; - assert(argc > 0); // every program has at least a progname - argv0 = strdup(argv[0]); // small memory leak, but fn only called once - assert(argv0); + assert(argc > 0); // every program has at least a name + argv0 = argv[0]; - string cmdline_string; // easier than doing strcats + cmdline.clear(); for (int i = 0; i < argc; i++) { - if (i != 0) { - cmdline_string += " "; - } - cmdline_string += argv[i]; + if (i != 0) cmdline += " "; + cmdline += argv[i]; argvs.push_back(argv[i]); } - cmdline = strdup(cmdline_string.c_str()); // another small memory leak - assert(cmdline); // Compute a simple sum of all the chars in argv - for (const char* c = cmdline; *c; c++) + argv_sum = 0; + for (string::const_iterator c = cmdline.begin(); c != cmdline.end(); ++c) { argv_sum += *c; + } } const vector<string>& GetArgvs() { return argvs; } -const char* GetArgv() { return cmdline; } -const char* GetArgv0() { return argv0; } +const char* GetArgv() { return cmdline.c_str(); } +const char* GetArgv0() { return argv0.c_str(); } uint32 GetArgvSum() { return argv_sum; } const char* ProgramInvocationName() { // like the GNU libc fn return GetArgv0(); } const char* ProgramInvocationShortName() { // like the GNU libc fn - const char* slash = strrchr(argv0, '/'); + size_t pos = argv0.rfind('/'); #ifdef OS_WINDOWS - if (!slash) slash = strrchr(argv0, '\\'); + if (pos == string::npos) pos = argv0.rfind('\\'); #endif - return slash ? slash + 1 : argv0; + return (pos == string::npos ? argv0.c_str() : (argv0.c_str() + pos + 1)); } void SetUsageMessage(const string& usage) { - if (program_usage != NULL) - ReportError(DIE, "ERROR: SetUsageMessage() called twice\n"); - program_usage = strdup(usage.c_str()); // small memory leak + program_usage = usage; } const char* ProgramUsage() { - if (program_usage) { - return program_usage; + if (program_usage.empty()) { + return "Warning: SetUsageMessage() never called"; } - return "Warning: SetUsageMessage() never called"; + return program_usage.c_str(); } // -------------------------------------------------------------------- @@ -1526,16 +1604,14 @@ const char* ProgramUsage() { // VersionString() // -------------------------------------------------------------------- -static const char* version_string = NULL; +static string version_string; void SetVersionString(const string& version) { - if (version_string != NULL) - ReportError(DIE, "ERROR: SetVersionString() called twice\n"); - version_string = strdup(version.c_str()); // small memory leak + version_string = version; } const char* VersionString() { - return version_string ? version_string : ""; + return version_string.c_str(); } @@ -1796,6 +1872,7 @@ bool ReadFromFlagsFile(const string& filename, const char* prog_name, // -------------------------------------------------------------------- // BoolFromEnv() // Int32FromEnv() +// Uint32FromEnv() // Int64FromEnv() // Uint64FromEnv() // DoubleFromEnv() @@ -1807,19 +1884,22 @@ bool ReadFromFlagsFile(const string& filename, const char* prog_name, // -------------------------------------------------------------------- bool BoolFromEnv(const char *v, bool dflt) { - return GetFromEnv(v, "bool", dflt); + return GetFromEnv(v, dflt); } int32 Int32FromEnv(const char *v, int32 dflt) { - return GetFromEnv(v, "int32", dflt); + return GetFromEnv(v, dflt); +} +uint32 Uint32FromEnv(const char *v, uint32 dflt) { + return GetFromEnv(v, dflt); } int64 Int64FromEnv(const char *v, int64 dflt) { - return GetFromEnv(v, "int64", dflt); + return GetFromEnv(v, dflt); } uint64 Uint64FromEnv(const char *v, uint64 dflt) { - return GetFromEnv(v, "uint64", dflt); + return GetFromEnv(v, dflt); } double DoubleFromEnv(const char *v, double dflt) { - return GetFromEnv(v, "double", dflt); + return GetFromEnv(v, dflt); } #ifdef _MSC_VER @@ -1855,6 +1935,10 @@ bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32)) { return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn)); } +bool RegisterFlagValidator(const uint32* flag, + bool (*validate_fn)(const char*, uint32)) { + return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn)); +} bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64)) { return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn)); @@ -1910,7 +1994,7 @@ static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv, HandleCommandLineHelpFlags(); // may cause us to exit on --help, etc. // See if any of the unset flags fail their validation checks - parser.ValidateAllFlags(); + parser.ValidateUnmodifiedFlags(); if (parser.ReportErrors()) // may cause us to exit on illegal flags gflags_exitfunc(1); diff --git a/extern/gflags/src/config.h b/extern/gflags/src/gflags/config.h index 8d20e222362..a65a94b0571 100644 --- a/extern/gflags/src/config.h +++ b/extern/gflags/src/gflags/config.h @@ -2,11 +2,15 @@ // Note: This header file is only used internally. It is not part of public interface! +#ifndef GFLAGS_CONFIG_H_ +#define GFLAGS_CONFIG_H_ + + // --------------------------------------------------------------------------- // System checks // Define if you build this library for a MS Windows OS. -#ifdef WIN32 +#ifdef _WIN32 # define OS_WINDOWS #endif @@ -58,19 +62,19 @@ #define PACKAGE_NAME gflags // Define to the full name and version of this package. -#define PACKAGE_STRING gflags 2.2.0 +#define PACKAGE_STRING gflags 2.2.1 // Define to the one symbol short name of this package. -#define PACKAGE_TARNAME gflags-2.2.0 +#define PACKAGE_TARNAME gflags-2.2.1 // Define to the version of this package. -#define PACKAGE_VERSION 2.2.0 +#define PACKAGE_VERSION 2.2.1 // Version number of package. #define VERSION PACKAGE_VERSION // Define to the address where bug reports for this package should be sent. -#define PACKAGE_BUGREPORT https://github.com/schuhschuh/gflags/issues +#define PACKAGE_BUGREPORT https://github.com/gflags/gflags/issues // --------------------------------------------------------------------------- // Path separator @@ -112,3 +116,6 @@ # endif # include "windows_port.h" #endif + + +#endif // GFLAGS_CONFIG_H_ diff --git a/extern/gflags/src/gflags/gflags.h b/extern/gflags/src/gflags/gflags.h index 357eec6be7c..02b40e158dc 100644 --- a/extern/gflags/src/gflags/gflags.h +++ b/extern/gflags/src/gflags/gflags.h @@ -81,12 +81,12 @@ #include <string> #include <vector> -#include "gflags_declare.h" // IWYU pragma: export +#include "gflags/gflags_declare.h" // IWYU pragma: export // We always want to export variables defined in user code #ifndef GFLAGS_DLL_DEFINE_FLAG -# ifdef _MSC_VER +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) # define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport) # else # define GFLAGS_DLL_DEFINE_FLAG @@ -128,6 +128,7 @@ namespace GFLAGS_NAMESPACE { // validator is already registered for this flag). extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32)); +extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64)); extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double)); @@ -284,7 +285,7 @@ class GFLAGS_DLL_DECL FlagSaver { FlagSaver(const FlagSaver&); // no copying! void operator=(const FlagSaver&); -}; +}__attribute((unused)); // -------------------------------------------------------------------- // Some deprecated or hopefully-soon-to-be-deprecated functions. @@ -313,6 +314,7 @@ extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval); extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval); +extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval); extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval); extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval); extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval); @@ -429,9 +431,14 @@ extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags(); class GFLAGS_DLL_DECL FlagRegisterer { public: - FlagRegisterer(const char* name, const char* type, + // We instantiate this template ctor for all supported types, + // so it is possible to place implementation of the FlagRegisterer ctor in + // .cc file. + // Calling this constructor with unsupported type will produce linker error. + template <typename FlagType> + FlagRegisterer(const char* name, const char* help, const char* filename, - void* current_storage, void* defvalue_storage); + FlagType* current_storage, FlagType* defvalue_storage); }; // If your application #defines STRIP_FLAG_HELP to a non-zero value @@ -473,7 +480,7 @@ extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[]; GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \ type FLAGS_no##name = FLAGS_nono##name; \ static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ - #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \ + #name, MAYBE_STRIPPED_HELP(help), __FILE__, \ &FLAGS_##name, &FLAGS_no##name); \ } \ using fL##shorttype::FLAGS_##name @@ -508,6 +515,10 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from); DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \ name, val, txt) +#define DEFINE_uint32(name,val, txt) \ + DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \ + name, val, txt) + #define DEFINE_int64(name, val, txt) \ DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \ name, val, txt) @@ -538,6 +549,26 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot, } inline clstring* dont_pass0toDEFINE_string(char *stringspot, int value); + +// Auxiliary class used to explicitly call destructor of string objects +// allocated using placement new during static program deinitialization. +// The destructor MUST be an inline function such that the explicit +// destruction occurs in the same compilation unit as the placement new. +class StringFlagDestructor { + void *current_storage_; + void *defvalue_storage_; + +public: + + StringFlagDestructor(void *current, void *defvalue) + : current_storage_(current), defvalue_storage_(defvalue) {} + + ~StringFlagDestructor() { + reinterpret_cast<clstring*>(current_storage_ )->~clstring(); + reinterpret_cast<clstring*>(defvalue_storage_)->~clstring(); + } +}; + } // namespace fLS // We need to define a var named FLAGS_no##name so people don't define @@ -550,13 +581,15 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot, #define DEFINE_string(name, val, txt) \ namespace fLS { \ using ::fLS::clstring; \ + using ::fLS::StringFlagDestructor; \ static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \ clstring* const FLAGS_no##name = ::fLS:: \ dont_pass0toDEFINE_string(s_##name[0].s, \ val); \ static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ - #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \ - s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ + #name, MAYBE_STRIPPED_HELP(txt), __FILE__, \ + FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ + static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \ extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \ using fLS::FLAGS_##name; \ clstring& FLAGS_##name = *FLAGS_no##name; \ diff --git a/extern/gflags/src/gflags/gflags_declare.h b/extern/gflags/src/gflags/gflags_declare.h index 9b85f46cfdc..98747f3cda1 100644 --- a/extern/gflags/src/gflags/gflags_declare.h +++ b/extern/gflags/src/gflags/gflags_declare.h @@ -45,18 +45,27 @@ // --------------------------------------------------------------------------- // Windows DLL import/export. -// We always want to import the symbols of the gflags library +// Whether gflags library is a DLL. +// +// Set to 1 by default when the shared gflags library was built on Windows. +// Must be overwritten when this header file is used with the optionally also +// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS. +#ifndef GFLAGS_IS_A_DLL +# define GFLAGS_IS_A_DLL 1 +#endif + +// We always want to import the symbols of the gflags library. #ifndef GFLAGS_DLL_DECL -# if 1 && defined(_MSC_VER) +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) # define GFLAGS_DLL_DECL __declspec(dllimport) # else # define GFLAGS_DLL_DECL # endif #endif -// We always want to import variables declared in user code +// We always want to import variables declared in user code. #ifndef GFLAGS_DLL_DECLARE_FLAG -# ifdef _MSC_VER +# if GFLAGS_IS_A_DLL && defined(_MSC_VER) # define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport) # else # define GFLAGS_DLL_DECLARE_FLAG @@ -120,6 +129,9 @@ typedef std::string clstring; #define DECLARE_int32(name) \ DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name) +#define DECLARE_uint32(name) \ + DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name) + #define DECLARE_int64(name) \ DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name) diff --git a/extern/gflags/src/gflags/gflags_gflags.h b/extern/gflags/src/gflags/gflags_gflags.h index 0c17825dd62..36d0ba1d54c 100644 --- a/extern/gflags/src/gflags/gflags_gflags.h +++ b/extern/gflags/src/gflags/gflags_gflags.h @@ -77,6 +77,7 @@ using GFLAGS_NAMESPACE::AppendFlagsIntoFile; using GFLAGS_NAMESPACE::ReadFromFlagsFile; using GFLAGS_NAMESPACE::BoolFromEnv; using GFLAGS_NAMESPACE::Int32FromEnv; +using GFLAGS_NAMESPACE::Uint32FromEnv; using GFLAGS_NAMESPACE::Int64FromEnv; using GFLAGS_NAMESPACE::Uint64FromEnv; using GFLAGS_NAMESPACE::DoubleFromEnv; diff --git a/extern/gflags/src/gflags_completions.cc b/extern/gflags/src/gflags_completions.cc index d7097caeef7..c663453c59c 100644 --- a/extern/gflags/src/gflags_completions.cc +++ b/extern/gflags/src/gflags_completions.cc @@ -46,11 +46,6 @@ // 5a) Force bash to place most-relevent groups at the top of the list // 5b) Trim most flag's descriptions to fit on a single terminal line - -#include "gflags_completions.h" - -#include "config.h" - #include <stdio.h> #include <stdlib.h> #include <string.h> // for strlen @@ -60,7 +55,11 @@ #include <utility> #include <vector> -#include "gflags.h" +#include "gflags_completions.h" + +#include "config.h" +#include "gflags/gflags.h" +#include "gflags/gflags_completions.h" #include "util.h" using std::set; @@ -122,7 +121,7 @@ static void CategorizeAllMatchingFlags( NotableFlags *notable_flags); static void TryFindModuleAndPackageDir( - const vector<CommandLineFlagInfo> all_flags, + const vector<CommandLineFlagInfo> &all_flags, string *module, string *package_dir); @@ -472,7 +471,7 @@ static void PushNameWithSuffix(vector<string>* suffixes, const char* suffix) { } static void TryFindModuleAndPackageDir( - const vector<CommandLineFlagInfo> all_flags, + const vector<CommandLineFlagInfo> &all_flags, string *module, string *package_dir) { module->clear(); diff --git a/extern/gflags/src/gflags_reporting.cc b/extern/gflags/src/gflags_reporting.cc index 9cc41a7488c..7cc66913459 100644 --- a/extern/gflags/src/gflags_reporting.cc +++ b/extern/gflags/src/gflags_reporting.cc @@ -56,8 +56,8 @@ #include <vector> #include "config.h" -#include "gflags.h" -#include "gflags_completions.h" +#include "gflags/gflags.h" +#include "gflags/gflags_completions.h" #include "util.h" @@ -126,7 +126,8 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) { string final_string = ""; int chars_in_line = 0; // how many chars in current line so far? while (1) { - assert(chars_left == strlen(c_string)); // Unless there's a \0 in there? + assert(static_cast<size_t>(chars_left) + == strlen(c_string)); // Unless there's a \0 in there? const char* newline = strchr(c_string, '\n'); if (newline == NULL && chars_in_line+chars_left < kLineLength) { // The whole remainder of the string fits on this line diff --git a/extern/gflags/src/mutex.h b/extern/gflags/src/mutex.h index ff96f2b67f7..7d7c364b795 100644 --- a/extern/gflags/src/mutex.h +++ b/extern/gflags/src/mutex.h @@ -106,7 +106,7 @@ #ifndef GFLAGS_MUTEX_H_ #define GFLAGS_MUTEX_H_ -#include "gflags_declare.h" // to figure out pthreads support +#include "gflags/gflags_declare.h" // to figure out pthreads support #if defined(NO_THREADS) typedef int MutexType; // to keep a lock-count @@ -166,7 +166,7 @@ class Mutex { // It inhibits work being done by the destructor, which makes it // safer for code that tries to acqiure this mutex in their global // destructor. - inline Mutex(LinkerInitialized); + explicit inline Mutex(LinkerInitialized); // Destructor inline ~Mutex(); @@ -197,7 +197,7 @@ class Mutex { inline void SetIsSafe() { is_safe_ = true; } // Catch the error of writing Mutex when intending MutexLock. - Mutex(Mutex* /*ignored*/) {} + explicit Mutex(Mutex* /*ignored*/) {} // Disallow "evil" constructors Mutex(const Mutex&); void operator=(const Mutex&); diff --git a/extern/gflags/src/util.h b/extern/gflags/src/util.h index fb59b38ddc4..164e3cf86ab 100644 --- a/extern/gflags/src/util.h +++ b/extern/gflags/src/util.h @@ -37,7 +37,6 @@ #include "config.h" #include <assert.h> -#include <config.h> #ifdef HAVE_INTTYPES_H # include <inttypes.h> #endif diff --git a/extern/gflags/src/windows_port.h b/extern/gflags/src/windows_port.h index 1f546996783..61cf5b7e3a1 100644 --- a/extern/gflags/src/windows_port.h +++ b/extern/gflags/src/windows_port.h @@ -69,10 +69,8 @@ extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size, extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size, const char *format, va_list ap); #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) -#if defined(_MSC_VER) && (_MSC_VER < 1400) #define va_copy(dst, src) (dst) = (src) #endif -#endif #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */ #ifdef _MSC_VER @@ -111,7 +109,9 @@ inline void setenv(const char* name, const char* value, int) { #define unlink _unlink #endif -#if !(defined(_MSC_VER) && _MSC_VER >= 1400) +#if defined(_MSC_VER) && _MSC_VER >= 1800 +#include <inttypes.h> +#else #define PRId32 "d" #define PRIu32 "u" #define PRId64 "I64d" |