Tue Aug 19 16:15:48 2008 Google Inc. <opensource@google.com>
* google-gflags: version 1.0rc1
* Move #include files from google/ to gflags/ (csilvers)
* Small optimizations to reduce binary (library) size (jyrki)
* BUGFIX: forgot a std:: in one of the .h files (csilvers)
* Speed up locking by making sure calls are inlined (ajenjo)
* 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
* PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
* PORTABILITY: fix code to compile under Visual Studio (ajenjo)
* PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
git-svn-id: https://gflags.googlecode.com/svn/trunk@25 6586e3c6-dcc4-952a-343f-ff74eb82781d
diff --git a/src/gflags.cc b/src/gflags.cc
index 3d4881a..893d585 100644
--- a/src/gflags.cc
+++ b/src/gflags.cc
@@ -89,20 +89,34 @@
// are, similarly, mostly hooks into the functionality described above.
#include "config.h"
+// This comes first to ensure we define __STDC_FORMAT_MACROS in time.
+#ifdef HAVE_INTTYPES_H
+#ifndef __STDC_FORMAT_MACROS
+# define __STDC_FORMAT_MACROS 1 // gcc requires this to get PRId64, etc.
+#endif
+#include <inttypes.h>
+#endif // HAVE_INTTYPES_H
#include <stdio.h> // for snprintf
#include <ctype.h>
#include <errno.h>
#include <string.h>
#include <assert.h>
+#ifdef HAVE_FNMATCH_H
#include <fnmatch.h>
+#endif // HAVE_FNMATCH_H
+#ifdef HAVE_PTHREAD
#include <pthread.h>
+#endif // HAVE_PTHREAD
+#ifdef HAVE_WINDOWS_H
+#include <windows.h>
+#endif // HAVE_WINDOWS_H
#include <iostream> // for cerr
#include <string>
#include <map>
#include <vector>
#include <utility> // for pair<>
#include <algorithm>
-#include "google/gflags.h"
+#include "gflags/gflags.h"
#ifndef PATH_SEPARATOR
#define PATH_SEPARATOR '/'
@@ -121,17 +135,31 @@
# define strtouint64 strtoul
#endif
+// If we have inttypes.h, it will have defined PRId32/etc for us. If
+// not, take our best guess.
+#ifndef PRId32
+# define PRId32 "d"
+#endif
+#ifndef PRId64
+# define PRId64 "lld"
+#endif
+#ifndef PRIu64
+# define PRIu64 "llu"
+#endif
+
using std::string;
using std::map;
using std::vector;
using std::pair;
using std::cerr;
+using std::sort;
// Special flags, type 1: the 'recursive' flags. They set another flag's val.
DEFINE_string(flagfile, "",
"load flags from file");
DEFINE_string(fromenv, "",
- "set flags from the environment [use 'export FLAGS_flag1=value']");
+ "set flags from the environment"
+ " [use 'export FLAGS_flag1=value']");
DEFINE_string(tryfromenv, "",
"set flags from the environment if present");
@@ -147,7 +175,7 @@
// The help message indicating that the commandline flag has been
// 'stripped'. It will not show up when doing "-help" and its
// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
-// before including google/gflags.h.
+// before including gflags/gflags.h.
// This is used by this file, and also in commandlineflags_reporting.cc
const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
@@ -191,9 +219,9 @@
string ToString() const;
private:
- friend class CommandLineFlag; // for many things, including Validate()
- friend class GOOGLE_NAMESPACE::FlagSaverImpl; // calls New()
- friend class FlagRegistry; // checks value_buffer_ for flags_by_ptr_ map
+ friend class CommandLineFlag; // for many things, including Validate()
+ friend class GOOGLE_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);
friend bool TryParseLocked(const class CommandLineFlag*, FlagValue*,
const char*, string*); // for New(), CopyFrom()
@@ -250,7 +278,7 @@
if (type_ == FV_BOOL) {
const char* kTrue[] = { "1", "t", "true", "y", "yes" };
const char* kFalse[] = { "0", "f", "false", "n", "no" };
- for (int i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
+ for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
if (strcasecmp(value, kTrue[i]) == 0) {
SET_VALUE_AS(bool, true);
return true;
@@ -307,7 +335,7 @@
return true;
}
default: {
- assert(false); // unknown type
+ assert(false); // unknown type
return false;
}
}
@@ -319,13 +347,13 @@
case FV_BOOL:
return VALUE_AS(bool) ? "true" : "false";
case FV_INT32:
- snprintf(intbuf, sizeof(intbuf), "%d", VALUE_AS(int32));
+ snprintf(intbuf, sizeof(intbuf), "%"PRId32, VALUE_AS(int32));
return intbuf;
case FV_INT64:
- snprintf(intbuf, sizeof(intbuf), "%lld", VALUE_AS(int64));
+ snprintf(intbuf, sizeof(intbuf), "%"PRId64, VALUE_AS(int64));
return intbuf;
case FV_UINT64:
- snprintf(intbuf, sizeof(intbuf), "%llu", VALUE_AS(uint64));
+ snprintf(intbuf, sizeof(intbuf), "%"PRIu64, VALUE_AS(uint64));
return intbuf;
case FV_DOUBLE:
snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
@@ -333,7 +361,8 @@
case FV_STRING:
return VALUE_AS(string);
default:
- assert(false); return ""; // unknown type
+ assert(false);
+ return ""; // unknown type
}
}
@@ -359,7 +388,7 @@
return reinterpret_cast<bool (*)(const char*, const string&)>(
validate_fn_proto)(flagname, VALUE_AS(string));
default:
- assert(false); // unknown type
+ assert(false); // unknown type
return false;
}
}
@@ -372,7 +401,7 @@
case FV_UINT64: return "uint64";
case FV_DOUBLE: return "double";
case FV_STRING: return "string";
- default: assert(false); return ""; // unknown type
+ default: assert(false); return ""; // unknown type
}
}
@@ -386,19 +415,19 @@
case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string);
- default: assert(false); return false; // unknown type
+ default: assert(false); return false; // unknown type
}
}
FlagValue* FlagValue::New() const {
switch (type_) {
- case FV_BOOL: return new FlagValue(new bool, "bool");
- case FV_INT32: return new FlagValue(new int32, "int32");
- case FV_INT64: return new FlagValue(new int64, "int64");
- case FV_UINT64: return new FlagValue(new uint64, "uint64");
- case FV_DOUBLE: return new FlagValue(new double, "double");
+ case FV_BOOL: return new FlagValue(new bool(false), "bool");
+ case FV_INT32: return new FlagValue(new int32(0), "int32");
+ case FV_INT64: return new FlagValue(new int64(0), "int64");
+ case FV_UINT64: return new FlagValue(new uint64(0), "uint64");
+ case FV_DOUBLE: return new FlagValue(new double(0.0), "double");
case FV_STRING: return new FlagValue(new string, "string");
- default: assert(false); return NULL; // assert false
+ default: assert(false); return NULL; // unknown type
}
}
@@ -411,7 +440,7 @@
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;
case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string)); break;
- default: assert(false); // unknown type
+ default: assert(false); // unknown type
}
}
@@ -449,10 +478,12 @@
bool ValidateCurrent() const { return Validate(*current_); }
private:
- friend class FlagRegistry; // for SetFlagLocked() and setting flags_by_ptr_
- friend class GOOGLE_NAMESPACE::FlagSaverImpl; // for cloning the values
+ // for SetFlagLocked() and setting flags_by_ptr_
+ friend class FlagRegistry;
+ friend class GOOGLE_NAMESPACE::FlagSaverImpl; // for cloning the values
friend bool GetCommandLineOption(const char*, string*, bool*);
- friend bool AddFlagValidator(const void*, ValidateFnProto); // set validate_fn
+ // set validate_fn
+ friend bool AddFlagValidator(const void*, ValidateFnProto);
// This copies all the non-const members: modified, processed, defvalue, etc.
void CopyFrom(const CommandLineFlag& src);
@@ -535,10 +566,11 @@
void CommandLineFlag::CopyFrom(const CommandLineFlag& src) {
// Note we only copy the non-const members; others are fixed at construct time
- modified_ = src.modified_;
- current_->CopyFrom(*src.current_);
- defvalue_->CopyFrom(*src.defvalue_);
- validate_fn_proto_ = src.validate_fn_proto_;
+ if (modified_ != src.modified_) modified_ = src.modified_;
+ if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_);
+ if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_);
+ if (validate_fn_proto_ != src.validate_fn_proto_)
+ validate_fn_proto_ = src.validate_fn_proto_;
}
bool CommandLineFlag::Validate(const FlagValue& value) const {
@@ -565,19 +597,17 @@
}
};
-#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
-
class FlagRegistry {
public:
- FlagRegistry() { SAFE_PTHREAD(pthread_mutex_init(&lock_, NULL)); }
- ~FlagRegistry() { SAFE_PTHREAD(pthread_mutex_destroy(&lock_)); }
+ FlagRegistry();
+ ~FlagRegistry();
+
+ void Lock();
+ void Unlock();
// Store a flag in this registry. Takes ownership of the given pointer.
void RegisterFlag(CommandLineFlag* flag);
- void Lock() { SAFE_PTHREAD(pthread_mutex_lock(&lock_)); }
- void Unlock() { SAFE_PTHREAD(pthread_mutex_unlock(&lock_)); }
-
// Returns the flag object for the specified name, or NULL if not found.
CommandLineFlag* FindFlagLocked(const char* name);
@@ -618,12 +648,20 @@
typedef map<const void*, CommandLineFlag*> FlagPtrMap;
FlagPtrMap flags_by_ptr_;
+#if defined(HAVE_PTHREAD)
pthread_mutex_t lock_;
+#elif defined(HAVE_INITIALIZECRITICALSECTION)
+ CRITICAL_SECTION lock_;
+#else
+#error "Need to define a mutual-exclusion object for your system"
+#endif
static FlagRegistry* global_registry_; // a singleton registry
- static pthread_once_t global_registry_once_;
- static int global_registry_once_nothreads_; // when we don't link pthreads
+ // If global_registry_ has not yet been initialized, this function allocates
+ // a new global registry. If InterlockedCompareExchange() is available, it
+ // does so in a thread-safe manner; otherwise, single-threaded execution (or
+ // serialization using pthread_once) is assumed.
static void InitGlobalRegistry();
// Disallow
@@ -631,14 +669,98 @@
FlagRegistry& operator=(const FlagRegistry&);
};
-class FlagRegistryLock {
- public:
- explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
- ~FlagRegistryLock() { fr_->Unlock(); }
- private:
- FlagRegistry *const fr_;
-};
+#if defined(HAVE_PTHREAD)
+// The pthread.h header is available. The pthreads library may or may not be
+// linked in with -lpthread. If that library is not linked in, then it is
+// assumed that all operations involving command-line flags will be
+// single-threaded.
+#define SAFE_PTHREAD(fncall) do { if ((fncall) != 0) abort(); } while (0)
+
+inline FlagRegistry::FlagRegistry() {
+ SAFE_PTHREAD(pthread_mutex_init(&lock_, NULL));
+}
+inline FlagRegistry::~FlagRegistry() {
+ SAFE_PTHREAD(pthread_mutex_destroy(&lock_));
+}
+
+inline void FlagRegistry::Lock() {
+ SAFE_PTHREAD(pthread_mutex_lock(&lock_));
+}
+inline void FlagRegistry::Unlock() {
+ SAFE_PTHREAD(pthread_mutex_unlock(&lock_));
+}
+
+// We want to use pthread_once here, for safety, but have to worry about
+// whether libpthread is linked in or not. We declare a weak version of
+// the function, so we'll always compile (if the weak version is the only
+// one that ends up existing, then pthread_once will be equal to NULL).
+#ifdef HAVE___ATTRIBUTE__
+ // __THROW is defined in glibc systems. It means, counter-intuitively,
+ // "This function will never throw an exception." It's an optional
+ // optimization tool, but we may need to use it to match glibc prototypes.
+# ifndef __THROW // I guess we're not on a glibc system
+# define __THROW // __THROW is just an optimization, so ok to make it ""
+# endif
+extern "C" int pthread_once(pthread_once_t *, void (*)(void))
+ __THROW __attribute__((weak));
+#endif
+
+FlagRegistry* FlagRegistry::GlobalRegistry() {
+ if (pthread_once) { // means we're linked with -lpthread
+ static pthread_once_t global_registry_once = PTHREAD_ONCE_INIT;
+ pthread_once(&global_registry_once, &InitGlobalRegistry);
+ } else {
+ // Assume single-threaded execution.
+ InitGlobalRegistry();
+ }
+ return global_registry_;
+}
+
+#elif defined(HAVE_INITIALIZECRITICALSECTION)
+// The Windows version of the thread-safe code uses EnterCriticalSection and
+// LeaveCriticalSection to serialize access to the registry.
+
+#ifndef HAVE_INTERLOCKEDCOMPAREEXCHANGE
+// InitializeCriticalSection is available, but InterlockedCompareExchange
+// is not. On a Windows system both should be available, and on Unix, neither
+// one should be available.
+#error "Please check settings for HAVE_INTERLOCKED... and HAVE_INITIALIZE..."
+#endif // !HAVE_INTERLOCKEDCOMPAREEXCHANGE
+
+inline FlagRegistry::FlagRegistry() { InitializeCriticalSection(&lock_); }
+inline FlagRegistry::~FlagRegistry() { DeleteCriticalSection(&lock_); }
+
+inline void FlagRegistry::Lock() { EnterCriticalSection(&lock_); }
+inline void FlagRegistry::Unlock() { LeaveCriticalSection(&lock_); }
+
+FlagRegistry* FlagRegistry::GlobalRegistry() {
+ InitGlobalRegistry();
+ return global_registry_;
+}
+#endif // !HAVE_PTHREAD && HAVE_INITIALIZECRITICALSECTION
+
+// Get the singleton FlagRegistry object
+FlagRegistry* FlagRegistry::global_registry_ = NULL;
+
+void FlagRegistry::InitGlobalRegistry() {
+ if (!global_registry_) {
+#ifdef HAVE_INTERLOCKEDCOMPAREEXCHANGE
+ FlagRegistry* new_global_registry = new FlagRegistry;
+ if (InterlockedCompareExchangePointer(
+ reinterpret_cast<void* volatile *>(&global_registry_),
+ new_global_registry,
+ NULL) != NULL) {
+ // Some other thread initialized global_registry_ first.
+ delete new_global_registry;
+ }
+#else // !HAVE_INTERLOCKEDCOMPAREEXCHANGE
+ // Assume single-threaded execution, or else that this function call was
+ // serialized using pthread_once.
+ global_registry_ = new FlagRegistry;
+#endif // HAVE_INTERLOCKEDCOMPAREEXCHANGE
+ }
+}
void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
Lock();
@@ -756,7 +878,7 @@
delete tentative_value;
return false;
} else if (!flag->Validate(*tentative_value)) {
- if (msg){
+ if (msg) {
*msg += (string(kError) + "failed validation of new value "
+ "'" + tentative_value->ToString() + "' for flag '" +
+ flag->name() + "'\n");
@@ -810,46 +932,21 @@
}
default: {
// unknown set_mode
- assert(false); return false;
+ assert(false);
+ return false;
}
}
return true;
}
-// Get the singleton FlagRegistry object
-FlagRegistry* FlagRegistry::global_registry_ = NULL;
-pthread_once_t FlagRegistry::global_registry_once_ = PTHREAD_ONCE_INIT;
-int FlagRegistry::global_registry_once_nothreads_ = 0;
-
-void FlagRegistry::InitGlobalRegistry() {
- global_registry_ = new FlagRegistry;
-}
-
-// We want to use pthread_once here, for safety, but have to worry about
-// whether libpthread is linked in or not. We declare a weak version of
-// the function, so we'll always compile (if the weak version is the only
-// one that ends up existing, then pthread_once will be equal to NULL).
-#ifdef HAVE___ATTRIBUTE__
- // __THROW is defined in glibc systems. It means, counter-intuitively,
- // "This function will never throw an exception." It's an optional
- // optimization tool, but we may need to use it to match glibc prototypes.
-# ifndef __THROW // I guess we're not on a glibc system
-# define __THROW // __THROW is just an optimization, so ok to make it ""
-# endif
-extern "C" int pthread_once(pthread_once_t *, void (*)(void))
- __THROW __attribute__((weak));
-#endif
-
-FlagRegistry* FlagRegistry::GlobalRegistry() {
- if (pthread_once) { // means we're running with pthreads
- pthread_once(&global_registry_once_, &FlagRegistry::InitGlobalRegistry);
- } else { // not running with pthreads: we're the only thread
- if (global_registry_once_nothreads_++ == 0)
- InitGlobalRegistry();
- }
- return global_registry_;
-}
+class FlagRegistryLock {
+ public:
+ explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
+ ~FlagRegistryLock() { fr_->Unlock(); }
+ private:
+ FlagRegistry *const fr_;
+};
// --------------------------------------------------------------------
// CommandLineFlagParser
@@ -915,14 +1012,15 @@
// These are called by ProcessSingleOptionLocked and, similarly, return
// new values if everything went ok, or the empty-string if not.
string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode);
+ // diff fromenv/tryfromenv
string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode,
- bool errors_are_fatal); // diff fromenv/tryfromenv
+ bool errors_are_fatal);
private:
FlagRegistry* const registry_;
- map<string, string> error_flags_; // map from name to error message
+ map<string, string> error_flags_; // map from name to error message
// This could be a set<string>, but we reuse the map to minimize the .o size
- map<string, string> undefined_names_; // --name for name that's not registered
+ map<string, string> undefined_names_; // --[flag] name was not registered
};
@@ -932,10 +1030,10 @@
p = strchr(value, ',');
int len;
if (p) {
- len = p - value;
+ len = static_cast<int>(p - value);
p++;
} else {
- len = strlen(value);
+ len = static_cast<int>(strlen(value));
}
if (len == 0) {
@@ -958,13 +1056,13 @@
#define PFATAL(s) do { perror(s); commandlineflags_exitfunc(1); } while (0)
static string ReadFileIntoString(const char* filename) {
- const int bufsize = 8092;
- char buffer[bufsize];
+ const int kBufSize = 8092;
+ char buffer[kBufSize];
string s;
FILE* fp = fopen(filename, "r");
if (!fp) PFATAL(filename);
- int n;
- while ( (n=fread(buffer, 1, bufsize, fp)) > 0 ) {
+ size_t n;
+ while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
if (ferror(fp)) PFATAL(filename);
s.append(buffer, n);
}
@@ -1019,8 +1117,13 @@
assert(strcmp(flag->type_name(), "bool") != 0);
if (i+1 >= first_nonopt) {
// This flag needs a value, but there is nothing available
- error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'" +
- + " is missing its argument\n");
+ error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
+ + " is missing its argument");
+ if (flag->help() && flag->help()[0] > '\001') {
+ // Be useful in case we have a non-stripped description.
+ error_flags_[key] += string("; flag description: ") + flag->help();
+ }
+ error_flags_[key] += "\n";
break; // we treat this as an unrecoverable error
} else {
value = (*argv)[++i]; // read next arg for value
@@ -1052,7 +1155,7 @@
string msg;
vector<string> filename_list;
ParseFlagList(flagval.c_str(), &filename_list); // take a list of filenames
- for (int i = 0; i < filename_list.size(); ++i) {
+ for (size_t i = 0; i < filename_list.size(); ++i) {
const char* file = filename_list[i].c_str();
msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode);
}
@@ -1069,7 +1172,7 @@
vector<string> flaglist;
ParseFlagList(flagval.c_str(), &flaglist);
- for (int i = 0; i < flaglist.size(); ++i) {
+ for (size_t i = 0; i < flaglist.size(); ++i) {
const char* flagname = flaglist[i].c_str();
CommandLineFlag* flag = registry_->FindFlagLocked(flagname);
if (flag == NULL) {
@@ -1123,7 +1226,6 @@
} else if (strcmp(flag->name(), "tryfromenv") == 0) {
msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false);
-
}
return msg;
@@ -1152,7 +1254,7 @@
if (!FLAGS_undefok.empty()) {
vector<string> flaglist;
ParseFlagList(FLAGS_undefok.c_str(), &flaglist);
- for (int i = 0; i < flaglist.size(); ++i)
+ for (size_t i = 0; i < flaglist.size(); ++i)
if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) {
error_flags_[flaglist[i]] = ""; // clear the error message
}
@@ -1161,13 +1263,13 @@
// are ok; we just silently ignore them now, and hope that a future
// parse will pick them up somehow.
if (allow_command_line_reparsing) {
- for (map<string,string>::const_iterator it = undefined_names_.begin();
+ for (map<string, string>::const_iterator it = undefined_names_.begin();
it != undefined_names_.end(); ++it)
error_flags_[it->first] = ""; // clear the error message
}
bool found_error = false;
- for (map<string,string>::const_iterator it = error_flags_.begin();
+ for (map<string, string>::const_iterator it = error_flags_.begin();
it != error_flags_.end(); ++it) {
if (!it->second.empty()) {
fprintf(stderr, "%s", it->second.c_str());
@@ -1190,7 +1292,8 @@
while (*flagfile_contents && isspace(*flagfile_contents))
++flagfile_contents;
line_end = strchr(flagfile_contents, '\n');
- int len = line_end ? line_end-flagfile_contents : strlen(flagfile_contents);
+ size_t len = line_end ? static_cast<size_t>(line_end - flagfile_contents)
+ : strlen(flagfile_contents);
string line(flagfile_contents, len);
// Each line can be one of four things:
@@ -1240,8 +1343,17 @@
space = word + strlen(word);
const string glob(word, space - word);
// We try matching both against the full argv0 and basename(argv0)
- if (fnmatch(glob.c_str(), ProgramInvocationName(), FNM_PATHNAME) == 0 ||
- fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0) {
+#ifdef HAVE_FNMATCH_H
+ if (fnmatch(glob.c_str(),
+ ProgramInvocationName(),
+ FNM_PATHNAME) == 0 ||
+ fnmatch(glob.c_str(),
+ ProgramInvocationShortName(),
+ FNM_PATHNAME) == 0) {
+#else // !HAVE_FNMATCH_H
+ if ((glob == ProgramInvocationName()) ||
+ (glob == ProgramInvocationShortName())) {
+#endif // HAVE_FNMATCH_H
flags_are_relevant = true;
}
}
@@ -1393,8 +1505,7 @@
static const char* cmdline = ""; // the entire command-line
static vector<string> argvs;
static uint32 argv_sum = 0;
-static const char* program_usage = "Warning: SetUsageMessage() never called";
-static bool program_usage_set = false;
+static const char* program_usage = NULL;
void SetArgv(int argc, const char** argv) {
static bool called_set_argv = false;
@@ -1407,11 +1518,11 @@
argv0 = strdup(argv[0]); // small memory leak, but fn only called once
assert(argv0);
- string cmdline_string = string(""); // easier than doing strcats
- argvs.clear();
+ string cmdline_string; // easier than doing strcats
for (int i = 0; i < argc; i++) {
- if (i != 0)
+ if (i != 0) {
cmdline_string += " ";
+ }
cmdline_string += argv[i];
argvs.push_back(argv[i]);
}
@@ -1419,7 +1530,6 @@
assert(cmdline);
// Compute a simple sum of all the chars in argv
- argv_sum = 0;
for (const char* c = cmdline; *c; c++)
argv_sum += *c;
}
@@ -1440,17 +1550,18 @@
}
void SetUsageMessage(const string& usage) {
- if (program_usage_set) {
- fprintf(stderr, "ERROR: SetUsageMessage() called more than once\n");
+ if (program_usage != NULL) {
+ fprintf(stderr, "ERROR: SetUsageMessage() called twice\n");
exit(1);
}
-
program_usage = strdup(usage.c_str()); // small memory leak
- program_usage_set = true;
}
const char* ProgramUsage() {
- return program_usage;
+ if (program_usage) {
+ return program_usage;
+ }
+ return "Warning: SetUsageMessage() never called";
}
// --------------------------------------------------------------------
@@ -1600,7 +1711,8 @@
void operator=(const FlagSaverImpl&);
};
-FlagSaver::FlagSaver() : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
+FlagSaver::FlagSaver()
+ : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
impl_->SaveFromRegistry();
}
@@ -1629,7 +1741,7 @@
const vector<CommandLineFlagInfo>& flags) {
vector<CommandLineFlagInfo>::const_iterator i;
- int retval_space = 0;
+ size_t retval_space = 0;
for (i = flags.begin(); i != flags.end(); ++i) {
// An (over)estimate of how much space it will take to print this flag
retval_space += i->name.length() + i->current_value.length() + 5;
@@ -1654,7 +1766,7 @@
}
bool ReadFlagsFromString(const string& flagfilecontents,
- const char* prog_name, // TODO(csilvers): nix this
+ const char* /*prog_name*/, // TODO(csilvers): nix this
bool errors_are_fatal) {
FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
FlagSaverImpl saved_states(registry);
@@ -1844,7 +1956,7 @@
// dlopen, to get the new flags. But you have to explicitly
// Allow() it; otherwise, you get the normal default behavior
// of unrecognized flags calling a fatal error.
-// TODO(csilvers): this isn't used. Just delete it?
+// TODO(csilvers): this isn't used. Just delete it?
// --------------------------------------------------------------------
void AllowCommandLineReparsing() {
@@ -1854,7 +1966,7 @@
uint32 ReparseCommandLineNonHelpFlags() {
// We make a copy of argc and argv to pass in
const vector<string>& argvs = GetArgvs();
- int tmp_argc = argvs.size();
+ int tmp_argc = static_cast<int>(argvs.size());
char** tmp_argv = new char* [tmp_argc + 1];
for (int i = 0; i < tmp_argc; ++i)
tmp_argv[i] = strdup(argvs[i].c_str()); // TODO(csilvers): don't dup