Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/gflags/src/gflags.cc')
-rw-r--r--extern/gflags/src/gflags.cc316
1 files changed, 200 insertions, 116 deletions
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);