1*08ab5237SOystein Eftevaag// Copyright (c) 2006, Google Inc. 2*08ab5237SOystein Eftevaag// All rights reserved. 3*08ab5237SOystein Eftevaag// 4*08ab5237SOystein Eftevaag// Redistribution and use in source and binary forms, with or without 5*08ab5237SOystein Eftevaag// modification, are permitted provided that the following conditions are 6*08ab5237SOystein Eftevaag// met: 7*08ab5237SOystein Eftevaag// 8*08ab5237SOystein Eftevaag// * Redistributions of source code must retain the above copyright 9*08ab5237SOystein Eftevaag// notice, this list of conditions and the following disclaimer. 10*08ab5237SOystein Eftevaag// * Redistributions in binary form must reproduce the above 11*08ab5237SOystein Eftevaag// copyright notice, this list of conditions and the following disclaimer 12*08ab5237SOystein Eftevaag// in the documentation and/or other materials provided with the 13*08ab5237SOystein Eftevaag// distribution. 14*08ab5237SOystein Eftevaag// * Neither the name of Google Inc. nor the names of its 15*08ab5237SOystein Eftevaag// contributors may be used to endorse or promote products derived from 16*08ab5237SOystein Eftevaag// this software without specific prior written permission. 17*08ab5237SOystein Eftevaag// 18*08ab5237SOystein Eftevaag// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19*08ab5237SOystein Eftevaag// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20*08ab5237SOystein Eftevaag// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21*08ab5237SOystein Eftevaag// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22*08ab5237SOystein Eftevaag// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23*08ab5237SOystein Eftevaag// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24*08ab5237SOystein Eftevaag// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25*08ab5237SOystein Eftevaag// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26*08ab5237SOystein Eftevaag// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27*08ab5237SOystein Eftevaag// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28*08ab5237SOystein Eftevaag// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29*08ab5237SOystein Eftevaag 30*08ab5237SOystein Eftevaag// --- 31*08ab5237SOystein Eftevaag// Revamped and reorganized by Craig Silverstein 32*08ab5237SOystein Eftevaag// 33*08ab5237SOystein Eftevaag// This is the file that should be included by any file which declares 34*08ab5237SOystein Eftevaag// or defines a command line flag or wants to parse command line flags 35*08ab5237SOystein Eftevaag// or print a program usage message (which will include information about 36*08ab5237SOystein Eftevaag// flags). Executive summary, in the form of an example foo.cc file: 37*08ab5237SOystein Eftevaag// 38*08ab5237SOystein Eftevaag// #include "foo.h" // foo.h has a line "DECLARE_int32(start);" 39*08ab5237SOystein Eftevaag// #include "validators.h" // hypothetical file defining ValidateIsFile() 40*08ab5237SOystein Eftevaag// 41*08ab5237SOystein Eftevaag// DEFINE_int32(end, 1000, "The last record to read"); 42*08ab5237SOystein Eftevaag// 43*08ab5237SOystein Eftevaag// DEFINE_string(filename, "my_file.txt", "The file to read"); 44*08ab5237SOystein Eftevaag// // Crash if the specified file does not exist. 45*08ab5237SOystein Eftevaag// static bool dummy = RegisterFlagValidator(&FLAGS_filename, 46*08ab5237SOystein Eftevaag// &ValidateIsFile); 47*08ab5237SOystein Eftevaag// 48*08ab5237SOystein Eftevaag// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...) 49*08ab5237SOystein Eftevaag// 50*08ab5237SOystein Eftevaag// void MyFunc() { 51*08ab5237SOystein Eftevaag// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end); 52*08ab5237SOystein Eftevaag// } 53*08ab5237SOystein Eftevaag// 54*08ab5237SOystein Eftevaag// Then, at the command-line: 55*08ab5237SOystein Eftevaag// ./foo --noverbose --start=5 --end=100 56*08ab5237SOystein Eftevaag// 57*08ab5237SOystein Eftevaag// For more details, see 58*08ab5237SOystein Eftevaag// doc/gflags.html 59*08ab5237SOystein Eftevaag// 60*08ab5237SOystein Eftevaag// --- A note about thread-safety: 61*08ab5237SOystein Eftevaag// 62*08ab5237SOystein Eftevaag// We describe many functions in this routine as being thread-hostile, 63*08ab5237SOystein Eftevaag// thread-compatible, or thread-safe. Here are the meanings we use: 64*08ab5237SOystein Eftevaag// 65*08ab5237SOystein Eftevaag// thread-safe: it is safe for multiple threads to call this routine 66*08ab5237SOystein Eftevaag// (or, when referring to a class, methods of this class) 67*08ab5237SOystein Eftevaag// concurrently. 68*08ab5237SOystein Eftevaag// thread-hostile: it is not safe for multiple threads to call this 69*08ab5237SOystein Eftevaag// routine (or methods of this class) concurrently. In gflags, 70*08ab5237SOystein Eftevaag// most thread-hostile routines are intended to be called early in, 71*08ab5237SOystein Eftevaag// or even before, main() -- that is, before threads are spawned. 72*08ab5237SOystein Eftevaag// thread-compatible: it is safe for multiple threads to read from 73*08ab5237SOystein Eftevaag// this variable (when applied to variables), or to call const 74*08ab5237SOystein Eftevaag// methods of this class (when applied to classes), as long as no 75*08ab5237SOystein Eftevaag// other thread is writing to the variable or calling non-const 76*08ab5237SOystein Eftevaag// methods of this class. 77*08ab5237SOystein Eftevaag 78*08ab5237SOystein Eftevaag#ifndef GFLAGS_GFLAGS_H_ 79*08ab5237SOystein Eftevaag#define GFLAGS_GFLAGS_H_ 80*08ab5237SOystein Eftevaag 81*08ab5237SOystein Eftevaag#include <string> 82*08ab5237SOystein Eftevaag#include <vector> 83*08ab5237SOystein Eftevaag 84*08ab5237SOystein Eftevaag#include "gflags/gflags_declare.h" // IWYU pragma: export 85*08ab5237SOystein Eftevaag 86*08ab5237SOystein Eftevaag 87*08ab5237SOystein Eftevaag// We always want to export variables defined in user code 88*08ab5237SOystein Eftevaag#ifndef GFLAGS_DLL_DEFINE_FLAG 89*08ab5237SOystein Eftevaag# if GFLAGS_IS_A_DLL && defined(_MSC_VER) 90*08ab5237SOystein Eftevaag# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport) 91*08ab5237SOystein Eftevaag# else 92*08ab5237SOystein Eftevaag# define GFLAGS_DLL_DEFINE_FLAG 93*08ab5237SOystein Eftevaag# endif 94*08ab5237SOystein Eftevaag#endif 95*08ab5237SOystein Eftevaag 96*08ab5237SOystein Eftevaag 97*08ab5237SOystein Eftevaagnamespace GFLAGS_NAMESPACE { 98*08ab5237SOystein Eftevaag 99*08ab5237SOystein Eftevaag 100*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 101*08ab5237SOystein Eftevaag// To actually define a flag in a file, use DEFINE_bool, 102*08ab5237SOystein Eftevaag// DEFINE_string, etc. at the bottom of this file. You may also find 103*08ab5237SOystein Eftevaag// it useful to register a validator with the flag. This ensures that 104*08ab5237SOystein Eftevaag// when the flag is parsed from the commandline, or is later set via 105*08ab5237SOystein Eftevaag// SetCommandLineOption, we call the validation function. It is _not_ 106*08ab5237SOystein Eftevaag// called when you assign the value to the flag directly using the = operator. 107*08ab5237SOystein Eftevaag// 108*08ab5237SOystein Eftevaag// The validation function should return true if the flag value is valid, and 109*08ab5237SOystein Eftevaag// false otherwise. If the function returns false for the new setting of the 110*08ab5237SOystein Eftevaag// flag, the flag will retain its current value. If it returns false for the 111*08ab5237SOystein Eftevaag// default value, ParseCommandLineFlags() will die. 112*08ab5237SOystein Eftevaag// 113*08ab5237SOystein Eftevaag// This function is safe to call at global construct time (as in the 114*08ab5237SOystein Eftevaag// example below). 115*08ab5237SOystein Eftevaag// 116*08ab5237SOystein Eftevaag// Example use: 117*08ab5237SOystein Eftevaag// static bool ValidatePort(const char* flagname, int32 value) { 118*08ab5237SOystein Eftevaag// if (value > 0 && value < 32768) // value is ok 119*08ab5237SOystein Eftevaag// return true; 120*08ab5237SOystein Eftevaag// printf("Invalid value for --%s: %d\n", flagname, (int)value); 121*08ab5237SOystein Eftevaag// return false; 122*08ab5237SOystein Eftevaag// } 123*08ab5237SOystein Eftevaag// DEFINE_int32(port, 0, "What port to listen on"); 124*08ab5237SOystein Eftevaag// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort); 125*08ab5237SOystein Eftevaag 126*08ab5237SOystein Eftevaag// Returns true if successfully registered, false if not (because the 127*08ab5237SOystein Eftevaag// first argument doesn't point to a command-line flag, or because a 128*08ab5237SOystein Eftevaag// validator is already registered for this flag). 129*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool)); 130*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32)); 131*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32)); 132*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64)); 133*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64)); 134*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double)); 135*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&)); 136*08ab5237SOystein Eftevaag 137*08ab5237SOystein Eftevaag// Convenience macro for the registration of a flag validator 138*08ab5237SOystein Eftevaag#define DEFINE_validator(name, validator) \ 139*08ab5237SOystein Eftevaag static const bool name##_validator_registered = \ 140*08ab5237SOystein Eftevaag GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator) 141*08ab5237SOystein Eftevaag 142*08ab5237SOystein Eftevaag 143*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 144*08ab5237SOystein Eftevaag// These methods are the best way to get access to info about the 145*08ab5237SOystein Eftevaag// list of commandline flags. Note that these routines are pretty slow. 146*08ab5237SOystein Eftevaag// GetAllFlags: mostly-complete info about the list, sorted by file. 147*08ab5237SOystein Eftevaag// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does) 148*08ab5237SOystein Eftevaag// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr 149*08ab5237SOystein Eftevaag// 150*08ab5237SOystein Eftevaag// In addition to accessing flags, you can also access argv[0] (the program 151*08ab5237SOystein Eftevaag// name) and argv (the entire commandline), which we sock away a copy of. 152*08ab5237SOystein Eftevaag// These variables are static, so you should only set them once. 153*08ab5237SOystein Eftevaag// 154*08ab5237SOystein Eftevaag// No need to export this data only structure from DLL, avoiding VS warning 4251. 155*08ab5237SOystein Eftevaagstruct CommandLineFlagInfo { 156*08ab5237SOystein Eftevaag std::string name; // the name of the flag 157*08ab5237SOystein Eftevaag std::string type; // the type of the flag: int32, etc 158*08ab5237SOystein Eftevaag std::string description; // the "help text" associated with the flag 159*08ab5237SOystein Eftevaag std::string current_value; // the current value, as a string 160*08ab5237SOystein Eftevaag std::string default_value; // the default value, as a string 161*08ab5237SOystein Eftevaag std::string filename; // 'cleaned' version of filename holding the flag 162*08ab5237SOystein Eftevaag bool has_validator_fn; // true if RegisterFlagValidator called on this flag 163*08ab5237SOystein Eftevaag bool is_default; // true if the flag has the default value and 164*08ab5237SOystein Eftevaag // has not been set explicitly from the cmdline 165*08ab5237SOystein Eftevaag // or via SetCommandLineOption 166*08ab5237SOystein Eftevaag const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo) 167*08ab5237SOystein Eftevaag}; 168*08ab5237SOystein Eftevaag 169*08ab5237SOystein Eftevaag// Using this inside of a validator is a recipe for a deadlock. 170*08ab5237SOystein Eftevaag// TODO(user) Fix locking when validators are running, to make it safe to 171*08ab5237SOystein Eftevaag// call validators during ParseAllFlags. 172*08ab5237SOystein Eftevaag// Also make sure then to uncomment the corresponding unit test in 173*08ab5237SOystein Eftevaag// gflags_unittest.sh 174*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT); 175*08ab5237SOystein Eftevaag// These two are actually defined in gflags_reporting.cc. 176*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does 177*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict); 178*08ab5237SOystein Eftevaag 179*08ab5237SOystein Eftevaag// Create a descriptive string for a flag. 180*08ab5237SOystein Eftevaag// Goes to some trouble to make pretty line breaks. 181*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag); 182*08ab5237SOystein Eftevaag 183*08ab5237SOystein Eftevaag// Thread-hostile; meant to be called before any threads are spawned. 184*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv); 185*08ab5237SOystein Eftevaag 186*08ab5237SOystein Eftevaag// The following functions are thread-safe as long as SetArgv() is 187*08ab5237SOystein Eftevaag// only called before any threads start. 188*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs(); 189*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string 190*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0 191*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv 192*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set 193*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0) 194*08ab5237SOystein Eftevaag 195*08ab5237SOystein Eftevaag// ProgramUsage() is thread-safe as long as SetUsageMessage() is only 196*08ab5237SOystein Eftevaag// called before any threads start. 197*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage() 198*08ab5237SOystein Eftevaag 199*08ab5237SOystein Eftevaag// VersionString() is thread-safe as long as SetVersionString() is only 200*08ab5237SOystein Eftevaag// called before any threads start. 201*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString() 202*08ab5237SOystein Eftevaag 203*08ab5237SOystein Eftevaag 204*08ab5237SOystein Eftevaag 205*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 206*08ab5237SOystein Eftevaag// Normally you access commandline flags by just saying "if (FLAGS_foo)" 207*08ab5237SOystein Eftevaag// or whatever, and set them by calling "FLAGS_foo = bar" (or, more 208*08ab5237SOystein Eftevaag// commonly, via the DEFINE_foo macro). But if you need a bit more 209*08ab5237SOystein Eftevaag// control, we have programmatic ways to get/set the flags as well. 210*08ab5237SOystein Eftevaag// These programmatic ways to access flags are thread-safe, but direct 211*08ab5237SOystein Eftevaag// access is only thread-compatible. 212*08ab5237SOystein Eftevaag 213*08ab5237SOystein Eftevaag// Return true iff the flagname was found. 214*08ab5237SOystein Eftevaag// OUTPUT is set to the flag's value, or unchanged if we return false. 215*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT); 216*08ab5237SOystein Eftevaag 217*08ab5237SOystein Eftevaag// Return true iff the flagname was found. OUTPUT is set to the flag's 218*08ab5237SOystein Eftevaag// CommandLineFlagInfo or unchanged if we return false. 219*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT); 220*08ab5237SOystein Eftevaag 221*08ab5237SOystein Eftevaag// Return the CommandLineFlagInfo of the flagname. exit() if name not found. 222*08ab5237SOystein Eftevaag// Example usage, to check if a flag's value is currently the default value: 223*08ab5237SOystein Eftevaag// if (GetCommandLineFlagInfoOrDie("foo").is_default) ... 224*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name); 225*08ab5237SOystein Eftevaag 226*08ab5237SOystein Eftevaagenum GFLAGS_DLL_DECL FlagSettingMode { 227*08ab5237SOystein Eftevaag // update the flag's value (can call this multiple times). 228*08ab5237SOystein Eftevaag SET_FLAGS_VALUE, 229*08ab5237SOystein Eftevaag // update the flag's value, but *only if* it has not yet been updated 230*08ab5237SOystein Eftevaag // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef". 231*08ab5237SOystein Eftevaag SET_FLAG_IF_DEFAULT, 232*08ab5237SOystein Eftevaag // set the flag's default value to this. If the flag has not yet updated 233*08ab5237SOystein Eftevaag // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef") 234*08ab5237SOystein Eftevaag // change the flag's current value to the new default value as well. 235*08ab5237SOystein Eftevaag SET_FLAGS_DEFAULT 236*08ab5237SOystein Eftevaag}; 237*08ab5237SOystein Eftevaag 238*08ab5237SOystein Eftevaag// Set a particular flag ("command line option"). Returns a string 239*08ab5237SOystein Eftevaag// describing the new value that the option has been set to. The 240*08ab5237SOystein Eftevaag// return value API is not well-specified, so basically just depend on 241*08ab5237SOystein Eftevaag// it to be empty if the setting failed for some reason -- the name is 242*08ab5237SOystein Eftevaag// not a valid flag name, or the value is not a valid value -- and 243*08ab5237SOystein Eftevaag// non-empty else. 244*08ab5237SOystein Eftevaag 245*08ab5237SOystein Eftevaag// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case) 246*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value); 247*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode); 248*08ab5237SOystein Eftevaag 249*08ab5237SOystein Eftevaag 250*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 251*08ab5237SOystein Eftevaag// Saves the states (value, default value, whether the user has set 252*08ab5237SOystein Eftevaag// the flag, registered validators, etc) of all flags, and restores 253*08ab5237SOystein Eftevaag// them when the FlagSaver is destroyed. This is very useful in 254*08ab5237SOystein Eftevaag// tests, say, when you want to let your tests change the flags, but 255*08ab5237SOystein Eftevaag// make sure that they get reverted to the original states when your 256*08ab5237SOystein Eftevaag// test is complete. 257*08ab5237SOystein Eftevaag// 258*08ab5237SOystein Eftevaag// Example usage: 259*08ab5237SOystein Eftevaag// void TestFoo() { 260*08ab5237SOystein Eftevaag// FlagSaver s1; 261*08ab5237SOystein Eftevaag// FLAG_foo = false; 262*08ab5237SOystein Eftevaag// FLAG_bar = "some value"; 263*08ab5237SOystein Eftevaag// 264*08ab5237SOystein Eftevaag// // test happens here. You can return at any time 265*08ab5237SOystein Eftevaag// // without worrying about restoring the FLAG values. 266*08ab5237SOystein Eftevaag// } 267*08ab5237SOystein Eftevaag// 268*08ab5237SOystein Eftevaag// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all 269*08ab5237SOystein Eftevaag// the work is done in the constructor and destructor, so in the standard 270*08ab5237SOystein Eftevaag// usage example above, the compiler would complain that it's an 271*08ab5237SOystein Eftevaag// unused variable. 272*08ab5237SOystein Eftevaag// 273*08ab5237SOystein Eftevaag// This class is thread-safe. However, its destructor writes to 274*08ab5237SOystein Eftevaag// exactly the set of flags that have changed value during its 275*08ab5237SOystein Eftevaag// lifetime, so concurrent _direct_ access to those flags 276*08ab5237SOystein Eftevaag// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe. 277*08ab5237SOystein Eftevaag 278*08ab5237SOystein Eftevaagclass GFLAGS_DLL_DECL FlagSaver { 279*08ab5237SOystein Eftevaag public: 280*08ab5237SOystein Eftevaag FlagSaver(); 281*08ab5237SOystein Eftevaag ~FlagSaver(); 282*08ab5237SOystein Eftevaag 283*08ab5237SOystein Eftevaag private: 284*08ab5237SOystein Eftevaag class FlagSaverImpl* impl_; // we use pimpl here to keep API steady 285*08ab5237SOystein Eftevaag 286*08ab5237SOystein Eftevaag FlagSaver(const FlagSaver&); // no copying! 287*08ab5237SOystein Eftevaag void operator=(const FlagSaver&); 288*08ab5237SOystein Eftevaag}@GFLAGS_ATTRIBUTE_UNUSED@; 289*08ab5237SOystein Eftevaag 290*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 291*08ab5237SOystein Eftevaag// Some deprecated or hopefully-soon-to-be-deprecated functions. 292*08ab5237SOystein Eftevaag 293*08ab5237SOystein Eftevaag// This is often used for logging. TODO(csilvers): figure out a better way 294*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString(); 295*08ab5237SOystein Eftevaag// Usually where this is used, a FlagSaver should be used instead. 296*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL 297*08ab5237SOystein Eftevaagbool ReadFlagsFromString(const std::string& flagfilecontents, 298*08ab5237SOystein Eftevaag const char* prog_name, 299*08ab5237SOystein Eftevaag bool errors_are_fatal); // uses SET_FLAGS_VALUE 300*08ab5237SOystein Eftevaag 301*08ab5237SOystein Eftevaag// These let you manually implement --flagfile functionality. 302*08ab5237SOystein Eftevaag// DEPRECATED. 303*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name); 304*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE 305*08ab5237SOystein Eftevaag 306*08ab5237SOystein Eftevaag 307*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 308*08ab5237SOystein Eftevaag// Useful routines for initializing flags from the environment. 309*08ab5237SOystein Eftevaag// In each case, if 'varname' does not exist in the environment 310*08ab5237SOystein Eftevaag// return defval. If 'varname' does exist but is not valid 311*08ab5237SOystein Eftevaag// (e.g., not a number for an int32 flag), abort with an error. 312*08ab5237SOystein Eftevaag// Otherwise, return the value. NOTE: for booleans, for true use 313*08ab5237SOystein Eftevaag// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'. 314*08ab5237SOystein Eftevaag 315*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval); 316*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval); 317*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval); 318*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval); 319*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval); 320*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval); 321*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval); 322*08ab5237SOystein Eftevaag 323*08ab5237SOystein Eftevaag 324*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 325*08ab5237SOystein Eftevaag// The next two functions parse gflags from main(): 326*08ab5237SOystein Eftevaag 327*08ab5237SOystein Eftevaag// Set the "usage" message for this program. For example: 328*08ab5237SOystein Eftevaag// string usage("This program does nothing. Sample usage:\n"); 329*08ab5237SOystein Eftevaag// usage += argv[0] + " <uselessarg1> <uselessarg2>"; 330*08ab5237SOystein Eftevaag// SetUsageMessage(usage); 331*08ab5237SOystein Eftevaag// Do not include commandline flags in the usage: we do that for you! 332*08ab5237SOystein Eftevaag// Thread-hostile; meant to be called before any threads are spawned. 333*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage); 334*08ab5237SOystein Eftevaag 335*08ab5237SOystein Eftevaag// Sets the version string, which is emitted with --version. 336*08ab5237SOystein Eftevaag// For instance: SetVersionString("1.3"); 337*08ab5237SOystein Eftevaag// Thread-hostile; meant to be called before any threads are spawned. 338*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void SetVersionString(const std::string& version); 339*08ab5237SOystein Eftevaag 340*08ab5237SOystein Eftevaag 341*08ab5237SOystein Eftevaag// Looks for flags in argv and parses them. Rearranges argv to put 342*08ab5237SOystein Eftevaag// flags first, or removes them entirely if remove_flags is true. 343*08ab5237SOystein Eftevaag// If a flag is defined more than once in the command line or flag 344*08ab5237SOystein Eftevaag// file, the last definition is used. Returns the index (into argv) 345*08ab5237SOystein Eftevaag// of the first non-flag argument. 346*08ab5237SOystein Eftevaag// See top-of-file for more details on this function. 347*08ab5237SOystein Eftevaag#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead. 348*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags); 349*08ab5237SOystein Eftevaag#endif 350*08ab5237SOystein Eftevaag 351*08ab5237SOystein Eftevaag 352*08ab5237SOystein Eftevaag// Calls to ParseCommandLineNonHelpFlags and then to 353*08ab5237SOystein Eftevaag// HandleCommandLineHelpFlags can be used instead of a call to 354*08ab5237SOystein Eftevaag// ParseCommandLineFlags during initialization, in order to allow for 355*08ab5237SOystein Eftevaag// changing default values for some FLAGS (via 356*08ab5237SOystein Eftevaag// e.g. SetCommandLineOptionWithMode calls) between the time of 357*08ab5237SOystein Eftevaag// command line parsing and the time of dumping help information for 358*08ab5237SOystein Eftevaag// the flags as a result of command line parsing. If a flag is 359*08ab5237SOystein Eftevaag// defined more than once in the command line or flag file, the last 360*08ab5237SOystein Eftevaag// definition is used. Returns the index (into argv) of the first 361*08ab5237SOystein Eftevaag// non-flag argument. (If remove_flags is true, will always return 1.) 362*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags); 363*08ab5237SOystein Eftevaag 364*08ab5237SOystein Eftevaag// This is actually defined in gflags_reporting.cc. 365*08ab5237SOystein Eftevaag// This function is misnamed (it also handles --version, etc.), but 366*08ab5237SOystein Eftevaag// it's too late to change that now. :-( 367*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc 368*08ab5237SOystein Eftevaag 369*08ab5237SOystein Eftevaag// Allow command line reparsing. Disables the error normally 370*08ab5237SOystein Eftevaag// generated when an unknown flag is found, since it may be found in a 371*08ab5237SOystein Eftevaag// later parse. Thread-hostile; meant to be called before any threads 372*08ab5237SOystein Eftevaag// are spawned. 373*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void AllowCommandLineReparsing(); 374*08ab5237SOystein Eftevaag 375*08ab5237SOystein Eftevaag// Reparse the flags that have not yet been recognized. Only flags 376*08ab5237SOystein Eftevaag// registered since the last parse will be recognized. Any flag value 377*08ab5237SOystein Eftevaag// must be provided as part of the argument using "=", not as a 378*08ab5237SOystein Eftevaag// separate command line argument that follows the flag argument. 379*08ab5237SOystein Eftevaag// Intended for handling flags from dynamically loaded libraries, 380*08ab5237SOystein Eftevaag// since their flags are not registered until they are loaded. 381*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags(); 382*08ab5237SOystein Eftevaag 383*08ab5237SOystein Eftevaag// Clean up memory allocated by flags. This is only needed to reduce 384*08ab5237SOystein Eftevaag// the quantity of "potentially leaked" reports emitted by memory 385*08ab5237SOystein Eftevaag// debugging tools such as valgrind. It is not required for normal 386*08ab5237SOystein Eftevaag// operation, or for the google perftools heap-checker. It must only 387*08ab5237SOystein Eftevaag// be called when the process is about to exit, and all threads that 388*08ab5237SOystein Eftevaag// might access flags are quiescent. Referencing flags after this is 389*08ab5237SOystein Eftevaag// called will have unexpected consequences. This is not safe to run 390*08ab5237SOystein Eftevaag// when multiple threads might be running: the function is 391*08ab5237SOystein Eftevaag// thread-hostile. 392*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL void ShutDownCommandLineFlags(); 393*08ab5237SOystein Eftevaag 394*08ab5237SOystein Eftevaag 395*08ab5237SOystein Eftevaag// -------------------------------------------------------------------- 396*08ab5237SOystein Eftevaag// Now come the command line flag declaration/definition macros that 397*08ab5237SOystein Eftevaag// will actually be used. They're kind of hairy. A major reason 398*08ab5237SOystein Eftevaag// for this is initialization: we want people to be able to access 399*08ab5237SOystein Eftevaag// variables in global constructors and have that not crash, even if 400*08ab5237SOystein Eftevaag// their global constructor runs before the global constructor here. 401*08ab5237SOystein Eftevaag// (Obviously, we can't guarantee the flags will have the correct 402*08ab5237SOystein Eftevaag// default value in that case, but at least accessing them is safe.) 403*08ab5237SOystein Eftevaag// The only way to do that is have flags point to a static buffer. 404*08ab5237SOystein Eftevaag// So we make one, using a union to ensure proper alignment, and 405*08ab5237SOystein Eftevaag// then use placement-new to actually set up the flag with the 406*08ab5237SOystein Eftevaag// correct default value. In the same vein, we have to worry about 407*08ab5237SOystein Eftevaag// flag access in global destructors, so FlagRegisterer has to be 408*08ab5237SOystein Eftevaag// careful never to destroy the flag-values it constructs. 409*08ab5237SOystein Eftevaag// 410*08ab5237SOystein Eftevaag// Note that when we define a flag variable FLAGS_<name>, we also 411*08ab5237SOystein Eftevaag// preemptively define a junk variable, FLAGS_no<name>. This is to 412*08ab5237SOystein Eftevaag// cause a link-time error if someone tries to define 2 flags with 413*08ab5237SOystein Eftevaag// names like "logging" and "nologging". We do this because a bool 414*08ab5237SOystein Eftevaag// flag FLAG can be set from the command line to true with a "-FLAG" 415*08ab5237SOystein Eftevaag// argument, and to false with a "-noFLAG" argument, and so this can 416*08ab5237SOystein Eftevaag// potentially avert confusion. 417*08ab5237SOystein Eftevaag// 418*08ab5237SOystein Eftevaag// We also put flags into their own namespace. It is purposefully 419*08ab5237SOystein Eftevaag// named in an opaque way that people should have trouble typing 420*08ab5237SOystein Eftevaag// directly. The idea is that DEFINE puts the flag in the weird 421*08ab5237SOystein Eftevaag// namespace, and DECLARE imports the flag from there into the current 422*08ab5237SOystein Eftevaag// namespace. The net result is to force people to use DECLARE to get 423*08ab5237SOystein Eftevaag// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;" 424*08ab5237SOystein Eftevaag// or some such instead. We want this so we can put extra 425*08ab5237SOystein Eftevaag// functionality (like sanity-checking) in DECLARE if we want, and 426*08ab5237SOystein Eftevaag// make sure it is picked up everywhere. 427*08ab5237SOystein Eftevaag// 428*08ab5237SOystein Eftevaag// We also put the type of the variable in the namespace, so that 429*08ab5237SOystein Eftevaag// people can't DECLARE_int32 something that they DEFINE_bool'd 430*08ab5237SOystein Eftevaag// elsewhere. 431*08ab5237SOystein Eftevaag 432*08ab5237SOystein Eftevaagclass GFLAGS_DLL_DECL FlagRegisterer { 433*08ab5237SOystein Eftevaag public: 434*08ab5237SOystein Eftevaag // We instantiate this template ctor for all supported types, 435*08ab5237SOystein Eftevaag // so it is possible to place implementation of the FlagRegisterer ctor in 436*08ab5237SOystein Eftevaag // .cc file. 437*08ab5237SOystein Eftevaag // Calling this constructor with unsupported type will produce linker error. 438*08ab5237SOystein Eftevaag template <typename FlagType> 439*08ab5237SOystein Eftevaag FlagRegisterer(const char* name, 440*08ab5237SOystein Eftevaag const char* help, const char* filename, 441*08ab5237SOystein Eftevaag FlagType* current_storage, FlagType* defvalue_storage); 442*08ab5237SOystein Eftevaag}; 443*08ab5237SOystein Eftevaag 444*08ab5237SOystein Eftevaag// Force compiler to not generate code for the given template specialization. 445*08ab5237SOystein Eftevaag#if defined(_MSC_VER) && _MSC_VER < 1800 // Visual Studio 2013 version 12.0 446*08ab5237SOystein Eftevaag #define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type) 447*08ab5237SOystein Eftevaag#else 448*08ab5237SOystein Eftevaag #define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type) \ 449*08ab5237SOystein Eftevaag extern template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \ 450*08ab5237SOystein Eftevaag const char* name, const char* help, const char* filename, \ 451*08ab5237SOystein Eftevaag type* current_storage, type* defvalue_storage) 452*08ab5237SOystein Eftevaag#endif 453*08ab5237SOystein Eftevaag 454*08ab5237SOystein Eftevaag// Do this for all supported flag types. 455*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(bool); 456*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int32); 457*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint32); 458*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int64); 459*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint64); 460*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(double); 461*08ab5237SOystein EftevaagGFLAGS_DECLARE_FLAG_REGISTERER_CTOR(std::string); 462*08ab5237SOystein Eftevaag 463*08ab5237SOystein Eftevaag#undef GFLAGS_DECLARE_FLAG_REGISTERER_CTOR 464*08ab5237SOystein Eftevaag 465*08ab5237SOystein Eftevaag// If your application #defines STRIP_FLAG_HELP to a non-zero value 466*08ab5237SOystein Eftevaag// before #including this file, we remove the help message from the 467*08ab5237SOystein Eftevaag// binary file. This can reduce the size of the resulting binary 468*08ab5237SOystein Eftevaag// somewhat, and may also be useful for security reasons. 469*08ab5237SOystein Eftevaag 470*08ab5237SOystein Eftevaagextern GFLAGS_DLL_DECL const char kStrippedFlagHelp[]; 471*08ab5237SOystein Eftevaag 472*08ab5237SOystein Eftevaag 473*08ab5237SOystein Eftevaag} // namespace GFLAGS_NAMESPACE 474*08ab5237SOystein Eftevaag 475*08ab5237SOystein Eftevaag 476*08ab5237SOystein Eftevaag#ifndef SWIG // In swig, ignore the main flag declarations 477*08ab5237SOystein Eftevaag 478*08ab5237SOystein Eftevaag#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0 479*08ab5237SOystein Eftevaag// Need this construct to avoid the 'defined but not used' warning. 480*08ab5237SOystein Eftevaag#define MAYBE_STRIPPED_HELP(txt) \ 481*08ab5237SOystein Eftevaag (false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp) 482*08ab5237SOystein Eftevaag#else 483*08ab5237SOystein Eftevaag#define MAYBE_STRIPPED_HELP(txt) txt 484*08ab5237SOystein Eftevaag#endif 485*08ab5237SOystein Eftevaag 486*08ab5237SOystein Eftevaag// Each command-line flag has two variables associated with it: one 487*08ab5237SOystein Eftevaag// with the current value, and one with the default value. However, 488*08ab5237SOystein Eftevaag// we have a third variable, which is where value is assigned; it's a 489*08ab5237SOystein Eftevaag// constant. This guarantees that FLAG_##value is initialized at 490*08ab5237SOystein Eftevaag// static initialization time (e.g. before program-start) rather than 491*08ab5237SOystein Eftevaag// than global construction time (which is after program-start but 492*08ab5237SOystein Eftevaag// before main), at least when 'value' is a compile-time constant. We 493*08ab5237SOystein Eftevaag// use a small trick for the "default value" variable, and call it 494*08ab5237SOystein Eftevaag// FLAGS_no<name>. This serves the second purpose of assuring a 495*08ab5237SOystein Eftevaag// compile error if someone tries to define a flag named no<name> 496*08ab5237SOystein Eftevaag// which is illegal (--foo and --nofoo both affect the "foo" flag). 497*08ab5237SOystein Eftevaag#define DEFINE_VARIABLE(type, shorttype, name, value, help) \ 498*08ab5237SOystein Eftevaag namespace fL##shorttype { \ 499*08ab5237SOystein Eftevaag static const type FLAGS_nono##name = value; \ 500*08ab5237SOystein Eftevaag /* We always want to export defined variables, dll or no */ \ 501*08ab5237SOystein Eftevaag GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \ 502*08ab5237SOystein Eftevaag static type FLAGS_no##name = FLAGS_nono##name; \ 503*08ab5237SOystein Eftevaag static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ 504*08ab5237SOystein Eftevaag #name, MAYBE_STRIPPED_HELP(help), __FILE__, \ 505*08ab5237SOystein Eftevaag &FLAGS_##name, &FLAGS_no##name); \ 506*08ab5237SOystein Eftevaag } \ 507*08ab5237SOystein Eftevaag using fL##shorttype::FLAGS_##name 508*08ab5237SOystein Eftevaag 509*08ab5237SOystein Eftevaag// For DEFINE_bool, we want to do the extra check that the passed-in 510*08ab5237SOystein Eftevaag// value is actually a bool, and not a string or something that can be 511*08ab5237SOystein Eftevaag// coerced to a bool. These declarations (no definition needed!) will 512*08ab5237SOystein Eftevaag// help us do that, and never evaluate From, which is important. 513*08ab5237SOystein Eftevaag// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires 514*08ab5237SOystein Eftevaag// that the compiler have different sizes for bool & double. Since 515*08ab5237SOystein Eftevaag// this is not guaranteed by the standard, we check it with a 516*08ab5237SOystein Eftevaag// COMPILE_ASSERT. 517*08ab5237SOystein Eftevaagnamespace fLB { 518*08ab5237SOystein Eftevaagstruct CompileAssert {}; 519*08ab5237SOystein Eftevaagtypedef CompileAssert expected_sizeof_double_neq_sizeof_bool[ 520*08ab5237SOystein Eftevaag (sizeof(double) != sizeof(bool)) ? 1 : -1]; 521*08ab5237SOystein Eftevaagtemplate<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from); 522*08ab5237SOystein EftevaagGFLAGS_DLL_DECL bool IsBoolFlag(bool from); 523*08ab5237SOystein Eftevaag} // namespace fLB 524*08ab5237SOystein Eftevaag 525*08ab5237SOystein Eftevaag// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros 526*08ab5237SOystein Eftevaag// are in a separate include, gflags_declare.h, for reducing 527*08ab5237SOystein Eftevaag// the physical transitive size for DECLARE use. 528*08ab5237SOystein Eftevaag#define DEFINE_bool(name, val, txt) \ 529*08ab5237SOystein Eftevaag namespace fLB { \ 530*08ab5237SOystein Eftevaag typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \ 531*08ab5237SOystein Eftevaag (sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \ 532*08ab5237SOystein Eftevaag } \ 533*08ab5237SOystein Eftevaag DEFINE_VARIABLE(bool, B, name, val, txt) 534*08ab5237SOystein Eftevaag 535*08ab5237SOystein Eftevaag#define DEFINE_int32(name, val, txt) \ 536*08ab5237SOystein Eftevaag DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \ 537*08ab5237SOystein Eftevaag name, val, txt) 538*08ab5237SOystein Eftevaag 539*08ab5237SOystein Eftevaag#define DEFINE_uint32(name,val, txt) \ 540*08ab5237SOystein Eftevaag DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \ 541*08ab5237SOystein Eftevaag name, val, txt) 542*08ab5237SOystein Eftevaag 543*08ab5237SOystein Eftevaag#define DEFINE_int64(name, val, txt) \ 544*08ab5237SOystein Eftevaag DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \ 545*08ab5237SOystein Eftevaag name, val, txt) 546*08ab5237SOystein Eftevaag 547*08ab5237SOystein Eftevaag#define DEFINE_uint64(name,val, txt) \ 548*08ab5237SOystein Eftevaag DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \ 549*08ab5237SOystein Eftevaag name, val, txt) 550*08ab5237SOystein Eftevaag 551*08ab5237SOystein Eftevaag#define DEFINE_double(name, val, txt) \ 552*08ab5237SOystein Eftevaag DEFINE_VARIABLE(double, D, name, val, txt) 553*08ab5237SOystein Eftevaag 554*08ab5237SOystein Eftevaag// Strings are trickier, because they're not a POD, so we can't 555*08ab5237SOystein Eftevaag// construct them at static-initialization time (instead they get 556*08ab5237SOystein Eftevaag// constructed at global-constructor time, which is much later). To 557*08ab5237SOystein Eftevaag// try to avoid crashes in that case, we use a char buffer to store 558*08ab5237SOystein Eftevaag// the string, which we can static-initialize, and then placement-new 559*08ab5237SOystein Eftevaag// into it later. It's not perfect, but the best we can do. 560*08ab5237SOystein Eftevaag 561*08ab5237SOystein Eftevaagnamespace fLS { 562*08ab5237SOystein Eftevaag 563*08ab5237SOystein Eftevaaginline clstring* dont_pass0toDEFINE_string(char *stringspot, 564*08ab5237SOystein Eftevaag const char *value) { 565*08ab5237SOystein Eftevaag return new(stringspot) clstring(value); 566*08ab5237SOystein Eftevaag} 567*08ab5237SOystein Eftevaaginline clstring* dont_pass0toDEFINE_string(char *stringspot, 568*08ab5237SOystein Eftevaag const clstring &value) { 569*08ab5237SOystein Eftevaag return new(stringspot) clstring(value); 570*08ab5237SOystein Eftevaag} 571*08ab5237SOystein Eftevaaginline clstring* dont_pass0toDEFINE_string(char *stringspot, 572*08ab5237SOystein Eftevaag int value); 573*08ab5237SOystein Eftevaag 574*08ab5237SOystein Eftevaag// Auxiliary class used to explicitly call destructor of string objects 575*08ab5237SOystein Eftevaag// allocated using placement new during static program deinitialization. 576*08ab5237SOystein Eftevaag// The destructor MUST be an inline function such that the explicit 577*08ab5237SOystein Eftevaag// destruction occurs in the same compilation unit as the placement new. 578*08ab5237SOystein Eftevaagclass StringFlagDestructor { 579*08ab5237SOystein Eftevaag void *current_storage_; 580*08ab5237SOystein Eftevaag void *defvalue_storage_; 581*08ab5237SOystein Eftevaag 582*08ab5237SOystein Eftevaagpublic: 583*08ab5237SOystein Eftevaag 584*08ab5237SOystein Eftevaag StringFlagDestructor(void *current, void *defvalue) 585*08ab5237SOystein Eftevaag : current_storage_(current), defvalue_storage_(defvalue) {} 586*08ab5237SOystein Eftevaag 587*08ab5237SOystein Eftevaag ~StringFlagDestructor() { 588*08ab5237SOystein Eftevaag reinterpret_cast<clstring*>(current_storage_ )->~clstring(); 589*08ab5237SOystein Eftevaag reinterpret_cast<clstring*>(defvalue_storage_)->~clstring(); 590*08ab5237SOystein Eftevaag } 591*08ab5237SOystein Eftevaag}; 592*08ab5237SOystein Eftevaag 593*08ab5237SOystein Eftevaag} // namespace fLS 594*08ab5237SOystein Eftevaag 595*08ab5237SOystein Eftevaag// We need to define a var named FLAGS_no##name so people don't define 596*08ab5237SOystein Eftevaag// --string and --nostring. And we need a temporary place to put val 597*08ab5237SOystein Eftevaag// so we don't have to evaluate it twice. Two great needs that go 598*08ab5237SOystein Eftevaag// great together! 599*08ab5237SOystein Eftevaag// The weird 'using' + 'extern' inside the fLS namespace is to work around 600*08ab5237SOystein Eftevaag// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See 601*08ab5237SOystein Eftevaag// http://code.google.com/p/google-gflags/issues/detail?id=20 602*08ab5237SOystein Eftevaag#define DEFINE_string(name, val, txt) \ 603*08ab5237SOystein Eftevaag namespace fLS { \ 604*08ab5237SOystein Eftevaag using ::fLS::clstring; \ 605*08ab5237SOystein Eftevaag using ::fLS::StringFlagDestructor; \ 606*08ab5237SOystein Eftevaag static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \ 607*08ab5237SOystein Eftevaag clstring* const FLAGS_no##name = ::fLS:: \ 608*08ab5237SOystein Eftevaag dont_pass0toDEFINE_string(s_##name[0].s, \ 609*08ab5237SOystein Eftevaag val); \ 610*08ab5237SOystein Eftevaag static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \ 611*08ab5237SOystein Eftevaag #name, MAYBE_STRIPPED_HELP(txt), __FILE__, \ 612*08ab5237SOystein Eftevaag FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \ 613*08ab5237SOystein Eftevaag static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \ 614*08ab5237SOystein Eftevaag extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \ 615*08ab5237SOystein Eftevaag using fLS::FLAGS_##name; \ 616*08ab5237SOystein Eftevaag clstring& FLAGS_##name = *FLAGS_no##name; \ 617*08ab5237SOystein Eftevaag } \ 618*08ab5237SOystein Eftevaag using fLS::FLAGS_##name 619*08ab5237SOystein Eftevaag 620*08ab5237SOystein Eftevaag#endif // SWIG 621*08ab5237SOystein Eftevaag 622*08ab5237SOystein Eftevaag 623*08ab5237SOystein Eftevaag@INCLUDE_GFLAGS_NS_H@ 624*08ab5237SOystein Eftevaag 625*08ab5237SOystein Eftevaag 626*08ab5237SOystein Eftevaag#endif // GFLAGS_GFLAGS_H_ 627