root/trunk/whisperlib/common/base/third-party/gflags.h

Revision 7, 18.3 kB (checked in by whispercastorg, 2 years ago)

version 0.2.0

Line 
1 // Copyright (c) 2006, Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 //     * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 //     * Redistributions in binary form must reproduce the above
11 // copyright notice, this list of conditions and the following disclaimer
12 // in the documentation and/or other materials provided with the
13 // distribution.
14 //     * Neither the name of Google Inc. nor the names of its
15 // contributors may be used to endorse or promote products derived from
16 // this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 // ---
31 // Author: Ray Sidney
32 // Revamped and reorganized by Craig Silverstein
33 //
34 // This is the file that should be included by any file which declares
35 // or defines a command line flag or wants to parse command line flags
36 // or print a program usage message (which will include information about
37 // flags).  Executive summary, in the form of an example foo.cc file:
38 //
39 //    #include "foo.h"         // foo.h has a line "DECLARE_int32(start);"
40 //
41 //    DEFINE_int32(end, 1000, "The last record to read");
42 //    DECLARE_bool(verbose);   // some other file has a DEFINE_bool(verbose, ...)
43 //
44 //    void MyFunc() {
45 //      if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
46 //    }
47 //
48 // Then, at the command-line:
49 //    ./foo --noverbose --start=5 --end=100
50 //
51 // For more details, see
52 //    doc/gflags.html
53
54 #ifndef BASE_COMMANDLINEFLAGS_H__
55 #define BASE_COMMANDLINEFLAGS_H__
56
57 #include <string>
58 #include <vector>
59
60 #include <sys/types.h>          // the normal place u_int16_t is defined
61
62 #include <whisperlib/common/base/types.h>
63
64 namespace google {
65
66 typedef int32 int32;
67 typedef int64 int64;
68 typedef uint64 uint64;
69
70
71 // --------------------------------------------------------------------
72 // These methods are the best way to get access to info about the
73 // list of commandline flags.  Note that these routines are pretty slow.
74 //   GetAllFlags: mostly-complete info about the list, sorted by file.
75 //   ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
76 //   ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
77 //
78 // In addition to accessing flags, you can also access argv[0] (the program
79 // name) and argv (the entire commandline), which we sock away a copy of.
80 // These variables are static, so you should only set them once.
81
82 struct CommandLineFlagInfo {
83   std::string name;           // the name of the flag
84   std::string type;           // the type of the flag: int32, etc
85   std::string description;    // the "help text" associated with the flag
86   std::string current_value;  // the current value, as a string
87   std::string default_value;  // the default value, as a string
88   std::string filename;       // 'cleaned' version of filename holding the flag
89   bool is_default;            // true if the flag has default value
90 };
91
92 extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
93 // These two are actually defined in commandlineflags_reporting.cc.
94 extern void ShowUsageWithFlags(const char *argv0);  // what --help does
95 extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
96
97 extern void SetArgv(int argc, const char** argv);
98 extern const std::vector<std::string>& GetArgvs();  // all of argv as a vector
99 extern const char* GetArgv();               // all of argv as a string
100 extern const char* GetArgv0();              // only argv0
101 extern uint32 GetArgvSum();                 // simple checksum of argv
102 extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
103 extern const char* ProgramInvocationShortName();   // basename(argv0)
104 extern const char* ProgramUsage();          // string set by SetUsageMessage()
105
106
107 // --------------------------------------------------------------------
108 // Normally you access commandline flags by just saying "if (FLAGS_foo)"
109 // or whatever, and set them by calling "FLAGS_foo = bar" (or, more
110 // commonly, via the DEFINE_foo macro).  But if you need a bit more
111 // control, we have programmatic ways to get/set the flags as well.
112
113 // Return true iff the flagname was found.
114 // OUTPUT is set to the flag's value, or unchanged if we return false.
115 extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
116
117 // Return true iff the flagname was found. OUTPUT is set to the flag's
118 // CommandLineFlagInfo or unchanged if we return false.
119 extern bool GetCommandLineFlagInfo(const char* name,
120                                    CommandLineFlagInfo* OUTPUT);
121
122 // Return the CommandLineFlagInfo of the flagname.  exit() if name not found.
123 // Example usage, to check if a flag's value is currently the default value:
124 //   if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
125 extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
126
127 enum FlagSettingMode {
128   // update the flag's value (can call this multiple times).
129   SET_FLAGS_VALUE,
130   // update the flag's value, but *only if* it has not yet been updated
131   // with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
132   SET_FLAG_IF_DEFAULT,
133   // set the flag's default value to this.  If the flag has not yet updated
134   // yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
135   // change the flag's current value to the new default value as well.
136   SET_FLAGS_DEFAULT
137 };
138
139 // Set a particular flag ("command line option").  Returns a string
140 // describing the new value that the option has been set to.  The
141 // return value API is not well-specified, so basically just depend on
142 // it to be empty if the setting failed for some reason -- the name is
143 // not a valid flag name, or the value is not a valid value -- and
144 // non-empty else.
145
146 // SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
147 extern std::string SetCommandLineOption(const char* name, const char* value);
148 extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
149                                                 FlagSettingMode set_mode);
150
151
152 // --------------------------------------------------------------------
153 // Saves the states (value, default value, whether the user has set
154 // the flag, etc) of all flags, and restores them when the FlagSaver
155 // is destroyed.  This is very useful in tests, say, when you want to
156 // let your tests change the flags, but make sure that they get
157 // reverted to the original states when your test is complete.
158 //
159 // Example usage:
160 //   void TestFoo() {
161 //     FlagSaver s1;
162 //     FLAG_foo = false;
163 //     FLAG_bar = "some value";
164 //
165 //     // test happens here.  You can return at any time
166 //     // without worrying about restoring the FLAG values.
167 //   }
168 //
169 // Note: This class is marked with __attribute__((unused)) because all the
170 // work is done in the constructor and destructor, so in the standard
171 // usage example above, the compiler would complain that it's an
172 // unused variable.
173
174 class FlagSaver {
175  public:
176   FlagSaver();
177   ~FlagSaver();
178
179  private:
180   class FlagSaverImpl* impl_;   // we use pimpl here to keep API steady
181
182   FlagSaver(const FlagSaver&);  // no copying!
183   void operator=(const FlagSaver&);
184 } __attribute__ ((unused));
185
186 // --------------------------------------------------------------------
187 // Some deprecated or hopefully-soon-to-be-deprecated functions.
188
189 // This is often used for logging.  TODO(csilvers): figure out a better way
190 extern std::string CommandlineFlagsIntoString();
191 // Usually where this is used, a FlagSaver should be used instead.
192 extern bool ReadFlagsFromString(const std::string& flagfilecontents,
193                                 const char* prog_name,
194                                 bool errors_are_fatal); // uses SET_FLAGS_VALUE
195
196 // These let you manually implement --flagfile functionality.
197 // DEPRECATED.
198 extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
199 extern bool SaveCommandFlags();  // actually defined in google.cc !
200 extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
201                               bool errors_are_fatal);   // uses SET_FLAGS_VALUE
202
203
204 // --------------------------------------------------------------------
205 // Useful routines for initializing flags from the environment.
206 // In each case, if 'varname' does not exist in the environment
207 // return defval.  If 'varname' does exist but is not valid
208 // (e.g., not a number for an int32 flag), abort with an error.
209 // Otherwise, return the value.  NOTE: for booleans, for true use
210 // 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
211
212 extern bool BoolFromEnv(const char *varname, bool defval);
213 extern int32 Int32FromEnv(const char *varname, int32 defval);
214 extern int64 Int64FromEnv(const char *varname, int64 defval);
215 extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
216 extern double DoubleFromEnv(const char *varname, double defval);
217 extern const char *StringFromEnv(const char *varname, const char *defval);
218
219
220 // --------------------------------------------------------------------
221 // The next two functions parse commandlineflags from main():
222
223 // Set the "usage" message for this program.  For example:
224 //   string usage("This program does nothing.  Sample usage:\n");
225 //   usage += argv[0] + " <uselessarg1> <uselessarg2>";
226 //   SetUsageMessage(usage);
227 // Do not include commandline flags in the usage: we do that for you!
228 extern void SetUsageMessage(const std::string& usage);
229
230 // Looks for flags in argv and parses them.  Rearranges argv to put
231 // flags first, or removes them entirely if remove_flags is true.
232 // If a flag is defined more than once in the command line or flag
233 // file, the last definition is used.
234 // See top-of-file for more details on this function.
235 #ifndef SWIG   // In swig, use ParseCommandLineFlagsScript() instead.
236 extern uint32 ParseCommandLineFlags(int *argc, char*** argv,
237                                     bool remove_flags);
238 #endif
239
240
241 // Calls to ParseCommandLineNonHelpFlags and then to
242 // HandleCommandLineHelpFlags can be used instead of a call to
243 // ParseCommandLineFlags during initialization, in order to allow for
244 // changing default values for some FLAGS (via
245 // e.g. SetCommandLineOptionWithMode calls) between the time of
246 // command line parsing and the time of dumping help information for
247 // the flags as a result of command line parsing.
248 // If a flag is defined more than once in the command line or flag
249 // file, the last definition is used.
250 extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
251                                            bool remove_flags);
252 // This is actually defined in commandlineflags_reporting.cc.
253 // This function is misnamed (it also handles --version, etc.), but
254 // it's too late to change that now. :-(
255 extern void HandleCommandLineHelpFlags();   // in commandlineflags_reporting.cc
256
257 // Allow command line reparsing.  Disables the error normaly generated
258 // when an unknown flag is found, since it may be found in a later parse.
259 extern void AllowCommandLineReparsing();
260
261 // Reparse the flags that have not yet been recognized.
262 // Only flags registered since the last parse will be recognized.
263 // Any flag value must be provided as part of the argument using "=",
264 // not as a separate command line argument that follows the flag argument.
265 // Intended for handling flags from dynamically loaded libraries,
266 // since their flags are not registered until they are loaded.
267 extern uint32 ReparseCommandLineNonHelpFlags();
268
269
270 // The following code is added to check if proper value types are passed to
271 // flags. Specially for boolean flags. Since almost anything can be implicitly
272 // casted to boolean many copy-paste type of errors got through and they are
273 // there in code now. As of now, flags_safe_cast is written such a way that
274 // it raises only warning for type mismatches.
275 //
276 // TODO(who?): This needs to be changed to give compilation error if type
277 // does not match.
278 extern void FlagsTypeWarn(const char *name);
279
280 template<typename From>
281 inline bool flags_safe_bool(From from, const char *name) {
282   FlagsTypeWarn(name);
283   return from;
284 }
285
286 inline bool flags_safe_bool(bool from, const char *name) {
287   return from;
288 }
289
290
291 // --------------------------------------------------------------------
292 // Now come the command line flag declaration/definition macros that
293 // will actually be used.  They're kind of hairy.  A major reason
294 // for this is initialization: we want people to be able to access
295 // variables in global constructors and have that not crash, even if
296 // their global constructor runs before the global constructor here.
297 // (Obviously, we can't guarantee the flags will have the correct
298 // default value in that case, but at least accessing them is safe.)
299 // The only way to do that is have flags point to a static buffer.
300 // So we make one, using a union to ensure proper alignment, and
301 // then use placement-new to actually set up the flag with the
302 // correct default value.  In the same vein, we have to worry about
303 // flag access in global destructors, so FlagRegisterer has to be
304 // careful never to destroy the flag-values it constructs.
305 //
306 // Note that when we define a flag variable FLAGS_<name>, we also
307 // preemptively define a junk variable, FLAGS_no<name>.  This is to
308 // cause a link-time error if someone tries to define 2 flags with
309 // names like "logging" and "nologging".  We do this because a bool
310 // flag FLAG can be set from the command line to true with a "-FLAG"
311 // argument, and to false with a "-noFLAG" argument, and so this can
312 // potentially avert confusion.
313 //
314 // We also put flags into their own namespace.  It is purposefully
315 // named in an opaque way that people should have trouble typing
316 // directly.  The idea is that DEFINE puts the flag in the weird
317 // namespace, and DECLARE imports the flag from there into the current
318 // namespace.  The net result is to force people to use DECLARE to get
319 // access to a flag, rather than saying "extern bool FLAGS_whatever;"
320 // or some such instead.  We want this so we can put extra
321 // functionality (like sanity-checking) in DECLARE if we want, and
322 // make sure it is picked up everywhere.
323 //
324 // We also put the type of the variable in the namespace, so that
325 // people can't DECLARE_int32 something that they DEFINE_bool'd
326 // elsewhere.
327
328 class FlagRegisterer {
329  public:
330   FlagRegisterer(const char* name, const char* type,
331                  const char* help, const char* filename,
332                  void* current_storage, void* defvalue_storage);
333  private:
334   class CommandLineFlag* flag_;
335 };
336
337 // namespc should be 'std::', and type 'string', for a var of type 'std::string'
338 #define DECLARE_VARIABLE(namespc, type, shorttype, name)        \
339   namespace fL##shorttype {                                     \
340     extern namespc type& FLAGS_##name;                          \
341   }                                                             \
342   using fL##shorttype::FLAGS_##name
343
344 // If your application #defines STRIP_FLAG_HELP to a non-zero value
345 // before #including this file, we remove the help message from the
346 // binary file. This can reduce the size of the resulting binary
347 // somewhat, and may also be useful for security reasons.
348
349 extern const char kStrippedFlagHelp[];
350
351 #if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
352 // Need this construct to avoid the 'defined but not used' warning.
353 #define MAYBE_STRIPPED_HELP(txt) (false ? (txt) : kStrippedFlagHelp)
354 #else
355 #define MAYBE_STRIPPED_HELP(txt) txt
356 #endif
357
358 // Each command-line flag defines an internal array of two elements
359 // of the appropriate time (each element is actually a union to get
360 // the values to be aligned on larger-than-byte boundaries).  Element
361 // 0 of the s_##name array holds the current value, and element 1
362 // holds the default value.
363 #define DEFINE_VARIABLE(namespc, type, shorttype, name, value, help)    \
364   namespace fL##shorttype {                                             \
365     static union { void* align; char store[sizeof(namespc type)]; }     \
366         s_##name[2];                                                    \
367     static google::FlagRegisterer o_##name(              \
368       #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__,               \
369       new (s_##name[0].store) namespc type(value),                      \
370       new (s_##name[1].store) namespc type(value));                     \
371     namespc type& FLAGS_##name =                                        \
372       *(reinterpret_cast<namespc type*>(s_##name[0].store));            \
373     char FLAGS_no##name __attribute__ ((unused));                    \
374   }                                                                     \
375   using fL##shorttype::FLAGS_##name
376
377
378 #ifndef SWIG  // In swig, ignore the main flag declarations
379
380 #define DECLARE_bool(name)          DECLARE_VARIABLE(, bool, B, name)
381 #define DEFINE_bool(name, val, txt) \
382     DEFINE_VARIABLE(, bool, B, name, google::flags_safe_bool(val, #name), txt)
383
384 #define DECLARE_int32(name)          DECLARE_VARIABLE(google::, int32,I, name)
385 #define DEFINE_int32(name, val,txt)  DEFINE_VARIABLE(google::, int32,I, name,val,txt)
386
387 #define DECLARE_int64(name)          DECLARE_VARIABLE(google::, int64,I64, name)
388 #define DEFINE_int64(name, val,txt)  DEFINE_VARIABLE(google::, int64,I64, name,val,txt)
389
390 #define DECLARE_uint64(name)         DECLARE_VARIABLE(google::, uint64,U64, name)
391 #define DEFINE_uint64(name, val,txt) DEFINE_VARIABLE(google::, uint64,U64,name,val,txt)
392
393 #define DECLARE_double(name)         DECLARE_VARIABLE(, double,D, name)
394 #define DEFINE_double(name, val,txt) DEFINE_VARIABLE(, double,D, name,val,txt)
395
396 #define DECLARE_string(name)         DECLARE_VARIABLE(std::, string,S, name)
397 #define DEFINE_string(name, val,txt) DEFINE_VARIABLE(std::, string,S, name,val,txt)
398
399 #endif  // SWIG
400
401 }
402
403 #endif  // BASE_COMMANDLINEFLAGS_H__
Note: See TracBrowser for help on using the browser.