mirror of
https://github.com/gflags/gflags.git
synced 2025-04-05 13:35:04 +00:00
* Reduce .o size by decomposing switches (jyrki)
* Document how to change the default flag value (csilvers) * Add a windows-specific README (csilvers) * A few comment updates (wojtekm) git-svn-id: https://gflags.googlecode.com/svn/trunk@39 6586e3c6-dcc4-952a-343f-ff74eb82781d
This commit is contained in:
parent
20500a9e59
commit
c44e0559cf
8 changed files with 125 additions and 48 deletions
|
@ -34,7 +34,7 @@ docdir = $(prefix)/share/doc/$(PACKAGE)-$(VERSION)
|
|||
## Add your documentation files (in doc/) in addition to these
|
||||
## top-level boilerplate files. Also add a TODO file if you have one.
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
|
||||
doc/designstyle.css doc/gflags.html
|
||||
README_windows.txt doc/designstyle.css doc/gflags.html
|
||||
|
||||
## The libraries (.so's) you want to install
|
||||
lib_LTLIBRARIES =
|
||||
|
|
|
@ -307,7 +307,7 @@ googleincludedir = $(includedir)/google
|
|||
googleinclude_HEADERS = src/google/gflags.h src/google/gflags_completions.h
|
||||
bin_SCRIPTS = src/gflags_completions.sh
|
||||
dist_doc_DATA = AUTHORS COPYING ChangeLog INSTALL NEWS README \
|
||||
doc/designstyle.css doc/gflags.html
|
||||
README_windows.txt doc/designstyle.css doc/gflags.html
|
||||
|
||||
lib_LTLIBRARIES = libgflags.la libgflags_nothreads.la
|
||||
WINDOWS_PROJECTS = google-gflags.sln \
|
||||
|
|
3
README
3
README
|
@ -6,5 +6,4 @@ module.
|
|||
See INSTALL for (generic) installation instructions for C++: basically
|
||||
./configure && make && make install
|
||||
|
||||
You can also compile this under Windows, if you want. The solution
|
||||
file (for VC 7.1 and later) is in this directory.
|
||||
See README_windows.txt for instructions on using under windows.
|
||||
|
|
20
README_windows.txt
Normal file
20
README_windows.txt
Normal file
|
@ -0,0 +1,20 @@
|
|||
You can compile this under Windows, if you want. The solution file
|
||||
(for VC 7.1 and later) is in this directory.
|
||||
|
||||
I've been told the following steps work to compile this under win64:
|
||||
1) Open the provided solution file
|
||||
2) Click on the Win32 target (on the right of Debug/Release)
|
||||
3) Choose Configuration Manager
|
||||
4) In Active Solution Platforms, choose New...
|
||||
5) In "Type of select the new platform", choose x64.
|
||||
In "Copy settings from:" choose Win32.
|
||||
6) Ok and then Close
|
||||
|
||||
I don't know very much about how to install DLLs on Windows, so you'll
|
||||
have to figure out that part for yourself. If you choose to just
|
||||
re-use the existing .sln, make sure you set the IncludeDir's
|
||||
appropriately! Look at the properties for libgflags.dll.
|
||||
|
||||
You can also link gflags code in statically. For this to work, you'll
|
||||
need to add "/D GFLAGS_DLL_DECL=" to the compile line of every
|
||||
gflags .cc file.
|
|
@ -47,6 +47,7 @@
|
|||
<dd> <a href="#together">Putting It Together: How to Set Up Flags</a> </dd>
|
||||
<dd> <a href="#commandline">Setting Flags on the Command Line</a> </dd>
|
||||
<dd> <a href="#varz">Setting Flags at Runtime</a> </dd>
|
||||
<dd> <a href="#default">Changing the Default Flag Value</a> </dd>
|
||||
<dd> <a href="#special">Special Flags</a> </dd>
|
||||
<dd> <a href="#api">The API</a> </dd>
|
||||
<dd> <br/> </dd>
|
||||
|
@ -348,6 +349,26 @@ the getopt library, nor do we allow "combining" flags behind a
|
|||
single dash, as in <code>ls -la</code>.</p>
|
||||
|
||||
|
||||
|
||||
<h2> <A name=default>Changing the Default Flag Value</A> </h2>
|
||||
|
||||
<p>Sometimes a flag is defined in a library, and you want to change
|
||||
its default value in one application but not others. It's simple to
|
||||
do this: just assign a new value to the flag in <code>main()</code>,
|
||||
before calling <code>ParseCommandLineFlags()</code>:</p>
|
||||
<pre>
|
||||
DECLARE_bool(lib_verbose); // mylib has a lib_verbose flag, default is false
|
||||
int main(int argc, char** argv) {
|
||||
FLAGS_lib_verbose = true; // in my app, I want a verbose lib by default
|
||||
ParseCommandLineFlags(...);
|
||||
}
|
||||
</pre>
|
||||
|
||||
<p>For this application, users can still set the flag value on the
|
||||
commandline, but if they do not, the flag's value will default to
|
||||
true.</p>
|
||||
|
||||
|
||||
<h2> <A name="special">Special Flags</code> </h2>
|
||||
|
||||
<p>There are a few flags defined by the commandlineflags module
|
||||
|
|
|
@ -143,6 +143,8 @@
|
|||
# define PRIu64 "llu"
|
||||
#endif
|
||||
|
||||
typedef unsigned char uint8;
|
||||
|
||||
// Special flags, type 1: the 'recursive' flags. They set another flag's val.
|
||||
DEFINE_string(flagfile, "",
|
||||
"load flags from file");
|
||||
|
@ -235,8 +237,15 @@ class FlagValue {
|
|||
friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
|
||||
const char*, string*); // for New(), CopyFrom()
|
||||
|
||||
enum ValueType {FV_BOOL, FV_INT32, FV_INT64, FV_UINT64, FV_DOUBLE, FV_STRING};
|
||||
|
||||
enum ValueType {
|
||||
FV_BOOL = 0,
|
||||
FV_INT32 = 1,
|
||||
FV_INT64 = 2,
|
||||
FV_UINT64 = 3,
|
||||
FV_DOUBLE = 4,
|
||||
FV_STRING = 5,
|
||||
FV_MAX_INDEX = 5,
|
||||
};
|
||||
const char* TypeName() const;
|
||||
bool Equal(const FlagValue& x) const;
|
||||
FlagValue* New() const; // creates a new one with default value
|
||||
|
@ -249,9 +258,8 @@ 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
|
||||
ValueType type_; // how to interpret value_
|
||||
uint32 type_; // how to interpret value_
|
||||
|
||||
FlagValue(const FlagValue&); // no copying!
|
||||
void operator=(const FlagValue&);
|
||||
|
@ -265,13 +273,12 @@ class FlagValue {
|
|||
#define SET_VALUE_AS(type, value) VALUE_AS(type) = (value)
|
||||
|
||||
FlagValue::FlagValue(void* valbuf, const char* type) : value_buffer_(valbuf) {
|
||||
if (strcmp(type, "bool") == 0) type_ = FV_BOOL;
|
||||
else if (strcmp(type, "int32") == 0) type_ = FV_INT32;
|
||||
else if (strcmp(type, "int64") == 0) type_ = FV_INT64;
|
||||
else if (strcmp(type, "uint64") == 0) type_ = FV_UINT64;
|
||||
else if (strcmp(type, "double") == 0) type_ = FV_DOUBLE;
|
||||
else if (strcmp(type, "string") == 0) type_ = FV_STRING;
|
||||
else assert(false); // Unknown typename
|
||||
for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
|
||||
if (!strcmp(type, TypeName())) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
assert(type_ <= FV_MAX_INDEX); // Unknown typename
|
||||
}
|
||||
|
||||
FlagValue::~FlagValue() {
|
||||
|
@ -405,15 +412,20 @@ bool FlagValue::Validate(const char* flagname,
|
|||
}
|
||||
|
||||
const char* FlagValue::TypeName() const {
|
||||
switch (type_) {
|
||||
case FV_BOOL: return "bool";
|
||||
case FV_INT32: return "int32";
|
||||
case FV_INT64: return "int64";
|
||||
case FV_UINT64: return "uint64";
|
||||
case FV_DOUBLE: return "double";
|
||||
case FV_STRING: return "string";
|
||||
default: assert(false); return ""; // unknown type
|
||||
static const char types[] =
|
||||
"bool\0xx"
|
||||
"int32\0x"
|
||||
"int64\0x"
|
||||
"uint64\0"
|
||||
"double\0"
|
||||
"string";
|
||||
if (type_ > FV_MAX_INDEX) {
|
||||
assert(false);
|
||||
return "";
|
||||
}
|
||||
// Directly indexing the strigns in the 'types' string, each of them
|
||||
// is 7 bytes long.
|
||||
return &types[type_ * 7];
|
||||
}
|
||||
|
||||
bool FlagValue::Equal(const FlagValue& x) const {
|
||||
|
@ -431,13 +443,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), "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");
|
||||
case FV_BOOL: return new FlagValue(new bool(false), type);
|
||||
case FV_INT32: return new FlagValue(new int32(0), type);
|
||||
case FV_INT64: return new FlagValue(new int64(0), type);
|
||||
case FV_UINT64: return new FlagValue(new uint64(0), type);
|
||||
case FV_DOUBLE: return new FlagValue(new double(0.0), type);
|
||||
case FV_STRING: return new FlagValue(new string, type);
|
||||
default: assert(false); return NULL; // unknown type
|
||||
}
|
||||
}
|
||||
|
@ -456,15 +469,19 @@ void FlagValue::CopyFrom(const FlagValue& x) {
|
|||
}
|
||||
|
||||
int FlagValue::ValueSize() const {
|
||||
switch (type_) {
|
||||
case FV_BOOL: return sizeof(bool);
|
||||
case FV_INT32: return sizeof(int32);
|
||||
case FV_INT64: return sizeof(int64);
|
||||
case FV_UINT64: return sizeof(uint64);
|
||||
case FV_DOUBLE: return sizeof(double);
|
||||
case FV_STRING: return sizeof(string);
|
||||
default: assert(false); return 0; // unknown type
|
||||
if (type_ > FV_MAX_INDEX) {
|
||||
assert(false); // unknown type
|
||||
return 0;
|
||||
}
|
||||
static const uint8 valuesize[] = {
|
||||
sizeof(bool),
|
||||
sizeof(int32),
|
||||
sizeof(int64),
|
||||
sizeof(uint64),
|
||||
sizeof(double),
|
||||
sizeof(string),
|
||||
};
|
||||
return valuesize[type_];
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
|
|
|
@ -124,7 +124,8 @@ typedef unsigned __int64 uint64;
|
|||
// DEFINE_string, etc. at the bottom of this file. You may also find
|
||||
// it useful to register a validator with the flag. This ensures that
|
||||
// when the flag is parsed from the commandline, or is later set via
|
||||
// SetCommandLineOption, we call the validation function.
|
||||
// SetCommandLineOption, we call the validation function. It is _not_
|
||||
// called when you assign the value to the flag directly using the = operator.
|
||||
//
|
||||
// The validation function should return true if the flag value is valid, and
|
||||
// false otherwise. If the function returns false for the new setting of the
|
||||
|
@ -180,7 +181,9 @@ struct CommandLineFlagInfo {
|
|||
std::string default_value; // the default value, as a string
|
||||
std::string filename; // 'cleaned' version of filename holding the flag
|
||||
bool has_validator_fn; // true if RegisterFlagValidator called on flag
|
||||
bool is_default; // true if the flag has default value
|
||||
bool is_default; // true if the flag has the default value and
|
||||
// has not been set explicitly from the cmdline
|
||||
// or via SetCommandLineOption
|
||||
};
|
||||
|
||||
// Using this inside of a validator is a recipe for a deadlock.
|
||||
|
|
|
@ -99,12 +99,26 @@
|
|||
#endif
|
||||
|
||||
// Annoying stuff for windows -- makes sure clients can import these functions
|
||||
#ifndef GFLAGS_DLL_DECL
|
||||
# ifdef _WIN32
|
||||
#if defined(_WIN32)
|
||||
# ifndef GFLAGS_DLL_DECL
|
||||
# define GFLAGS_DLL_DECL __declspec(dllimport)
|
||||
# else
|
||||
# endif
|
||||
# ifndef GFLAGS_DLL_DECLARE_FLAG
|
||||
# define GFLAGS_DLL_DECLARE_FLAG __declspec(import)
|
||||
# endif
|
||||
# ifndef GFLAGS_DLL_DEFINE_FLAG
|
||||
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
|
||||
# endif
|
||||
#else
|
||||
# ifndef GFLAGS_DLL_DECL
|
||||
# define GFLAGS_DLL_DECL
|
||||
# endif
|
||||
# ifndef GFLAGS_DLL_DECLARE_FLAG
|
||||
# define GFLAGS_DLL_DECLARE_FLAG
|
||||
# endif
|
||||
# ifndef GFLAGS_DLL_DEFINE_FLAG
|
||||
# define GFLAGS_DLL_DEFINE_FLAG
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace google {
|
||||
|
@ -133,7 +147,8 @@ typedef unsigned __int64 uint64;
|
|||
// DEFINE_string, etc. at the bottom of this file. You may also find
|
||||
// it useful to register a validator with the flag. This ensures that
|
||||
// when the flag is parsed from the commandline, or is later set via
|
||||
// SetCommandLineOption, we call the validation function.
|
||||
// SetCommandLineOption, we call the validation function. It is _not_
|
||||
// called when you assign the value to the flag directly using the = operator.
|
||||
//
|
||||
// The validation function should return true if the flag value is valid, and
|
||||
// false otherwise. If the function returns false for the new setting of the
|
||||
|
@ -189,7 +204,9 @@ struct GFLAGS_DLL_DECL CommandLineFlagInfo {
|
|||
std::string default_value; // the default value, as a string
|
||||
std::string filename; // 'cleaned' version of filename holding the flag
|
||||
bool has_validator_fn; // true if RegisterFlagValidator called on flag
|
||||
bool is_default; // true if the flag has default value
|
||||
bool is_default; // true if the flag has the default value and
|
||||
// has not been set explicitly from the cmdline
|
||||
// or via SetCommandLineOption
|
||||
};
|
||||
|
||||
// Using this inside of a validator is a recipe for a deadlock.
|
||||
|
@ -471,7 +488,7 @@ extern const char kStrippedFlagHelp[];
|
|||
namespace fL##shorttype { \
|
||||
static const type FLAGS_nono##name = value; \
|
||||
/* We always want to export defined variables, dll or no */ \
|
||||
__declspec(dllexport) type FLAGS_##name = FLAGS_nono##name; \
|
||||
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
|
||||
type FLAGS_no##name = FLAGS_nono##name; \
|
||||
static ::google::FlagRegisterer o_##name( \
|
||||
#name, #type, MAYBE_STRIPPED_HELP(help), __FILE__, \
|
||||
|
@ -482,7 +499,7 @@ extern const char kStrippedFlagHelp[];
|
|||
#define DECLARE_VARIABLE(type, shorttype, name) \
|
||||
namespace fL##shorttype { \
|
||||
/* We always want to import declared variables, dll or no */ \
|
||||
extern __declspec(dllimport) type FLAGS_##name; \
|
||||
extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; \
|
||||
} \
|
||||
using fL##shorttype::FLAGS_##name
|
||||
|
||||
|
@ -528,7 +545,7 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
|
|||
// try to avoid crashes in that case, we use a char buffer to store
|
||||
// the string, which we can static-initialize, and then placement-new
|
||||
// into it later. It's not perfect, but the best we can do.
|
||||
#define DECLARE_string(name) namespace fLS { extern __declspec(dllimport) std::string& FLAGS_##name; } \
|
||||
#define DECLARE_string(name) namespace fLS { extern GFLAGS_DLL_DECLARE_FLAG std::string& FLAGS_##name; } \
|
||||
using fLS::FLAGS_##name
|
||||
|
||||
// We need to define a var named FLAGS_no##name so people don't define
|
||||
|
@ -545,7 +562,7 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
|
|||
static ::google::FlagRegisterer o_##name( \
|
||||
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
|
||||
s_##name[0].s, new (s_##name[1].s) std::string(*FLAGS_no##name)); \
|
||||
extern __declspec(dllexport) std::string& FLAGS_##name; \
|
||||
extern GFLAGS_DLL_DEFINE_FLAG std::string& FLAGS_##name; \
|
||||
using fLS::FLAGS_##name; \
|
||||
std::string& FLAGS_##name = *FLAGS_no##name; \
|
||||
} \
|
||||
|
|
Loading…
Add table
Reference in a new issue