1 // Copyright (c) 1999, 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 // Revamped and reorganized by Craig Silverstein
32 //
33 // This file contains the implementation of all our command line flags
34 // stuff.  Here's how everything fits together
35 //
36 // * FlagRegistry owns CommandLineFlags owns FlagValue.
37 // * FlagSaver holds a FlagRegistry (saves it at construct time,
38 //     restores it at destroy time).
39 // * CommandLineFlagParser lives outside that hierarchy, but works on
40 //     CommandLineFlags (modifying the FlagValues).
41 // * Free functions like SetCommandLineOption() work via one of the
42 //     above (such as CommandLineFlagParser).
43 //
44 // In more detail:
45 //
46 // -- The main classes that hold flag data:
47 //
48 // FlagValue holds the current value of a flag.  It's
49 // pseudo-templatized: every operation on a FlagValue is typed.  It
50 // also deals with storage-lifetime issues (so flag values don't go
51 // away in a destructor), which is why we need a whole class to hold a
52 // variable's value.
53 //
54 // CommandLineFlag is all the information about a single command-line
55 // flag.  It has a FlagValue for the flag's current value, but also
56 // the flag's name, type, etc.
57 //
58 // FlagRegistry is a collection of CommandLineFlags.  There's the
59 // global registry, which is where flags defined via DEFINE_foo()
60 // live.  But it's possible to define your own flag, manually, in a
61 // different registry you create.  (In practice, multiple registries
62 // are used only by FlagSaver).
63 //
64 // A given FlagValue is owned by exactly one CommandLineFlag.  A given
65 // CommandLineFlag is owned by exactly one FlagRegistry.  FlagRegistry
66 // has a lock; any operation that writes to a FlagValue or
67 // CommandLineFlag owned by that registry must acquire the
68 // FlagRegistry lock before doing so.
69 //
70 // --- Some other classes and free functions:
71 //
72 // CommandLineFlagInfo is a client-exposed version of CommandLineFlag.
73 // Once it's instantiated, it has no dependencies or relationships
74 // with any other part of this file.
75 //
76 // FlagRegisterer is the helper class used by the DEFINE_* macros to
77 // allow work to be done at global initialization time.
78 //
79 // CommandLineFlagParser is the class that reads from the commandline
80 // and instantiates flag values based on that.  It needs to poke into
81 // the innards of the FlagValue->CommandLineFlag->FlagRegistry class
82 // hierarchy to do that.  It's careful to acquire the FlagRegistry
83 // lock before doing any writing or other non-const actions.
84 //
85 // GetCommandLineOption is just a hook into registry routines to
86 // retrieve a flag based on its name.  SetCommandLineOption, on the
87 // other hand, hooks into CommandLineFlagParser.  Other API functions
88 // are, similarly, mostly hooks into the functionality described above.
89 
90 // This comes first to ensure we define __STDC_FORMAT_MACROS in time.
91 #include <config.h>
92 #if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
93 # define __STDC_FORMAT_MACROS 1   // gcc requires this to get PRId64, etc.
94 #endif
95 
96 #include <gflags/gflags.h>
97 #include <assert.h>
98 #include <ctype.h>
99 #include <errno.h>
100 #ifdef HAVE_FNMATCH_H
101 # include <fnmatch.h>
102 #endif
103 #include <stdarg.h> // For va_list and related operations
104 #include <stdio.h>
105 #include <string.h>
106 
107 #include <algorithm>
108 #include <map>
109 #include <string>
110 #include <utility>     // for pair<>
111 #include <vector>
112 #include "mutex.h"
113 #include "util.h"
114 
115 #ifndef PATH_SEPARATOR
116 #define PATH_SEPARATOR  '/'
117 #endif
118 
119 
120 // Special flags, type 1: the 'recursive' flags.  They set another flag's val.
121 DEFINE_string(flagfile, "",
122               "load flags from file");
123 DEFINE_string(fromenv, "",
124               "set flags from the environment"
125               " [use 'export FLAGS_flag1=value']");
126 DEFINE_string(tryfromenv, "",
127               "set flags from the environment if present");
128 
129 // Special flags, type 2: the 'parsing' flags.  They modify how we parse.
130 DEFINE_string(undefok, "",
131               "comma-separated list of flag names that it is okay to specify "
132               "on the command line even if the program does not define a flag "
133               "with that name.  IMPORTANT: flags in this list that have "
134               "arguments MUST use the flag=value format");
135 
136 _START_GOOGLE_NAMESPACE_
137 
138 using std::map;
139 using std::pair;
140 using std::sort;
141 using std::string;
142 using std::vector;
143 
144 // This is used by the unittest to test error-exit code
145 void GFLAGS_DLL_DECL (*gflags_exitfunc)(int) = &exit;  // from stdlib.h
146 
147 
148 // The help message indicating that the commandline flag has been
149 // 'stripped'. It will not show up when doing "-help" and its
150 // variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
151 // before including base/gflags.h
152 
153 // This is used by this file, and also in gflags_reporting.cc
154 const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
155 
156 namespace {
157 
158 // There are also 'reporting' flags, in gflags_reporting.cc.
159 
160 static const char kError[] = "ERROR: ";
161 
162 // Indicates that undefined options are to be ignored.
163 // Enables deferred processing of flags in dynamically loaded libraries.
164 static bool allow_command_line_reparsing = false;
165 
166 static bool logging_is_probably_set_up = false;
167 
168 // This is a 'prototype' validate-function.  'Real' validate
169 // functions, take a flag-value as an argument: ValidateFn(bool) or
170 // ValidateFn(uint64).  However, for easier storage, we strip off this
171 // argument and then restore it when actually calling the function on
172 // a flag value.
173 typedef bool (*ValidateFnProto)();
174 
175 // Whether we should die when reporting an error.
176 enum DieWhenReporting { DIE, DO_NOT_DIE };
177 
178 // Report Error and exit if requested.
ReportError(DieWhenReporting should_die,const char * format,...)179 static void ReportError(DieWhenReporting should_die, const char* format, ...) {
180   char error_message[255];
181   va_list ap;
182   va_start(ap, format);
183   vsnprintf(error_message, sizeof(error_message), format, ap);
184   va_end(ap);
185   fprintf(stderr, "%s", error_message);
186   fflush(stderr);   // should be unnecessary, but cygwin's rxvt buffers stderr
187   if (should_die == DIE) gflags_exitfunc(1);
188 }
189 
190 
191 // --------------------------------------------------------------------
192 // FlagValue
193 //    This represent the value a single flag might have.  The major
194 //    functionality is to convert from a string to an object of a
195 //    given type, and back.  Thread-compatible.
196 // --------------------------------------------------------------------
197 
198 class CommandLineFlag;
199 class FlagValue {
200  public:
201   FlagValue(void* valbuf, const char* type, bool transfer_ownership_of_value);
202   ~FlagValue();
203 
204   bool ParseFrom(const char* spec);
205   string ToString() const;
206 
207  private:
208   friend class CommandLineFlag;  // for many things, including Validate()
209   friend class GOOGLE_NAMESPACE::FlagSaverImpl;  // calls New()
210   friend class FlagRegistry;     // checks value_buffer_ for flags_by_ptr_ map
211   template <typename T> friend T GetFromEnv(const char*, const char*, T);
212   friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
213                              const char*, string*);  // for New(), CopyFrom()
214 
215   enum ValueType {
216     FV_BOOL = 0,
217     FV_INT32 = 1,
218     FV_INT64 = 2,
219     FV_UINT64 = 3,
220     FV_DOUBLE = 4,
221     FV_STRING = 5,
222     FV_MAX_INDEX = 5,
223   };
224   const char* TypeName() const;
225   bool Equal(const FlagValue& x) const;
226   FlagValue* New() const;   // creates a new one with default value
227   void CopyFrom(const FlagValue& x);
228   int ValueSize() const;
229 
230   // Calls the given validate-fn on value_buffer_, and returns
231   // whatever it returns.  But first casts validate_fn_proto to a
232   // function that takes our value as an argument (eg void
233   // (*validate_fn)(bool) for a bool flag).
234   bool Validate(const char* flagname, ValidateFnProto validate_fn_proto) const;
235 
236   void* value_buffer_;          // points to the buffer holding our data
237   int8 type_;                   // how to interpret value_
238   bool owns_value_;         // whether to free value on destruct
239 
240   FlagValue(const FlagValue&);   // no copying!
241   void operator=(const FlagValue&);
242 };
243 
244 
245 // This could be a templated method of FlagValue, but doing so adds to the
246 // size of the .o.  Since there's no type-safety here anyway, macro is ok.
247 #define VALUE_AS(type)  *reinterpret_cast<type*>(value_buffer_)
248 #define OTHER_VALUE_AS(fv, type)  *reinterpret_cast<type*>(fv.value_buffer_)
249 #define SET_VALUE_AS(type, value)  VALUE_AS(type) = (value)
250 
FlagValue(void * valbuf,const char * type,bool transfer_ownership_of_value)251 FlagValue::FlagValue(void* valbuf, const char* type,
252                      bool transfer_ownership_of_value)
253     : value_buffer_(valbuf),
254       owns_value_(transfer_ownership_of_value) {
255   for (type_ = 0; type_ <= FV_MAX_INDEX; ++type_) {
256     if (!strcmp(type, TypeName())) {
257       break;
258     }
259   }
260   assert(type_ <= FV_MAX_INDEX);  // Unknown typename
261 }
262 
~FlagValue()263 FlagValue::~FlagValue() {
264   if (!owns_value_) {
265     return;
266   }
267   switch (type_) {
268     case FV_BOOL: delete reinterpret_cast<bool*>(value_buffer_); break;
269     case FV_INT32: delete reinterpret_cast<int32*>(value_buffer_); break;
270     case FV_INT64: delete reinterpret_cast<int64*>(value_buffer_); break;
271     case FV_UINT64: delete reinterpret_cast<uint64*>(value_buffer_); break;
272     case FV_DOUBLE: delete reinterpret_cast<double*>(value_buffer_); break;
273     case FV_STRING: delete reinterpret_cast<string*>(value_buffer_); break;
274   }
275 }
276 
ParseFrom(const char * value)277 bool FlagValue::ParseFrom(const char* value) {
278   if (type_ == FV_BOOL) {
279     const char* kTrue[] = { "1", "t", "true", "y", "yes" };
280     const char* kFalse[] = { "0", "f", "false", "n", "no" };
281     COMPILE_ASSERT(sizeof(kTrue) == sizeof(kFalse), true_false_equal);
282     for (size_t i = 0; i < sizeof(kTrue)/sizeof(*kTrue); ++i) {
283       if (strcasecmp(value, kTrue[i]) == 0) {
284         SET_VALUE_AS(bool, true);
285         return true;
286       } else if (strcasecmp(value, kFalse[i]) == 0) {
287         SET_VALUE_AS(bool, false);
288         return true;
289       }
290     }
291     return false;   // didn't match a legal input
292 
293   } else if (type_ == FV_STRING) {
294     SET_VALUE_AS(string, value);
295     return true;
296   }
297 
298   // OK, it's likely to be numeric, and we'll be using a strtoXXX method.
299   if (value[0] == '\0')   // empty-string is only allowed for string type.
300     return false;
301   char* end;
302   // Leading 0x puts us in base 16.  But leading 0 does not put us in base 8!
303   // It caused too many bugs when we had that behavior.
304   int base = 10;    // by default
305   if (value[0] == '0' && (value[1] == 'x' || value[1] == 'X'))
306     base = 16;
307   errno = 0;
308 
309   switch (type_) {
310     case FV_INT32: {
311       const int64 r = strto64(value, &end, base);
312       if (errno || end != value + strlen(value))  return false;  // bad parse
313       if (static_cast<int32>(r) != r)  // worked, but number out of range
314         return false;
315       SET_VALUE_AS(int32, static_cast<int32>(r));
316       return true;
317     }
318     case FV_INT64: {
319       const int64 r = strto64(value, &end, base);
320       if (errno || end != value + strlen(value))  return false;  // bad parse
321       SET_VALUE_AS(int64, r);
322       return true;
323     }
324     case FV_UINT64: {
325       while (*value == ' ') value++;
326       if (*value == '-') return false;  // negative number
327       const uint64 r = strtou64(value, &end, base);
328       if (errno || end != value + strlen(value))  return false;  // bad parse
329       SET_VALUE_AS(uint64, r);
330       return true;
331     }
332     case FV_DOUBLE: {
333       const double r = strtod(value, &end);
334       if (errno || end != value + strlen(value))  return false;  // bad parse
335       SET_VALUE_AS(double, r);
336       return true;
337     }
338     default: {
339       assert(false);  // unknown type
340       return false;
341     }
342   }
343 }
344 
ToString() const345 string FlagValue::ToString() const {
346   char intbuf[64];    // enough to hold even the biggest number
347   switch (type_) {
348     case FV_BOOL:
349       return VALUE_AS(bool) ? "true" : "false";
350     case FV_INT32:
351       snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32));
352       return intbuf;
353     case FV_INT64:
354       snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64));
355       return intbuf;
356     case FV_UINT64:
357       snprintf(intbuf, sizeof(intbuf), "%" PRIu64, VALUE_AS(uint64));
358       return intbuf;
359     case FV_DOUBLE:
360       snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
361       return intbuf;
362     case FV_STRING:
363       return VALUE_AS(string);
364     default:
365       assert(false);
366       return "";  // unknown type
367   }
368 }
369 
Validate(const char * flagname,ValidateFnProto validate_fn_proto) const370 bool FlagValue::Validate(const char* flagname,
371                          ValidateFnProto validate_fn_proto) const {
372   switch (type_) {
373     case FV_BOOL:
374       return reinterpret_cast<bool (*)(const char*, bool)>(
375           validate_fn_proto)(flagname, VALUE_AS(bool));
376     case FV_INT32:
377       return reinterpret_cast<bool (*)(const char*, int32)>(
378           validate_fn_proto)(flagname, VALUE_AS(int32));
379     case FV_INT64:
380       return reinterpret_cast<bool (*)(const char*, int64)>(
381           validate_fn_proto)(flagname, VALUE_AS(int64));
382     case FV_UINT64:
383       return reinterpret_cast<bool (*)(const char*, uint64)>(
384           validate_fn_proto)(flagname, VALUE_AS(uint64));
385     case FV_DOUBLE:
386       return reinterpret_cast<bool (*)(const char*, double)>(
387           validate_fn_proto)(flagname, VALUE_AS(double));
388     case FV_STRING:
389       return reinterpret_cast<bool (*)(const char*, const string&)>(
390           validate_fn_proto)(flagname, VALUE_AS(string));
391     default:
392       assert(false);  // unknown type
393       return false;
394   }
395 }
396 
TypeName() const397 const char* FlagValue::TypeName() const {
398   static const char types[] =
399       "bool\0xx"
400       "int32\0x"
401       "int64\0x"
402       "uint64\0"
403       "double\0"
404       "string";
405   if (type_ > FV_MAX_INDEX) {
406     assert(false);
407     return "";
408   }
409   // Directly indexing the strigns in the 'types' string, each of them
410   // is 7 bytes long.
411   return &types[type_ * 7];
412 }
413 
Equal(const FlagValue & x) const414 bool FlagValue::Equal(const FlagValue& x) const {
415   if (type_ != x.type_)
416     return false;
417   switch (type_) {
418     case FV_BOOL:   return VALUE_AS(bool) == OTHER_VALUE_AS(x, bool);
419     case FV_INT32:  return VALUE_AS(int32) == OTHER_VALUE_AS(x, int32);
420     case FV_INT64:  return VALUE_AS(int64) == OTHER_VALUE_AS(x, int64);
421     case FV_UINT64: return VALUE_AS(uint64) == OTHER_VALUE_AS(x, uint64);
422     case FV_DOUBLE: return VALUE_AS(double) == OTHER_VALUE_AS(x, double);
423     case FV_STRING: return VALUE_AS(string) == OTHER_VALUE_AS(x, string);
424     default: assert(false); return false;  // unknown type
425   }
426 }
427 
New() const428 FlagValue* FlagValue::New() const {
429   const char *type = TypeName();
430   switch (type_) {
431     case FV_BOOL:   return new FlagValue(new bool(false), type, true);
432     case FV_INT32:  return new FlagValue(new int32(0), type, true);
433     case FV_INT64:  return new FlagValue(new int64(0), type, true);
434     case FV_UINT64: return new FlagValue(new uint64(0), type, true);
435     case FV_DOUBLE: return new FlagValue(new double(0.0), type, true);
436     case FV_STRING: return new FlagValue(new string, type, true);
437     default: assert(false); return NULL;  // unknown type
438   }
439 }
440 
CopyFrom(const FlagValue & x)441 void FlagValue::CopyFrom(const FlagValue& x) {
442   assert(type_ == x.type_);
443   switch (type_) {
444     case FV_BOOL:   SET_VALUE_AS(bool, OTHER_VALUE_AS(x, bool));      break;
445     case FV_INT32:  SET_VALUE_AS(int32, OTHER_VALUE_AS(x, int32));    break;
446     case FV_INT64:  SET_VALUE_AS(int64, OTHER_VALUE_AS(x, int64));    break;
447     case FV_UINT64: SET_VALUE_AS(uint64, OTHER_VALUE_AS(x, uint64));  break;
448     case FV_DOUBLE: SET_VALUE_AS(double, OTHER_VALUE_AS(x, double));  break;
449     case FV_STRING: SET_VALUE_AS(string, OTHER_VALUE_AS(x, string));  break;
450     default: assert(false);  // unknown type
451   }
452 }
453 
ValueSize() const454 int FlagValue::ValueSize() const {
455   if (type_ > FV_MAX_INDEX) {
456     assert(false);  // unknown type
457     return 0;
458   }
459   static const uint8 valuesize[] = {
460     sizeof(bool),
461     sizeof(int32),
462     sizeof(int64),
463     sizeof(uint64),
464     sizeof(double),
465     sizeof(string),
466   };
467   return valuesize[type_];
468 }
469 
470 // --------------------------------------------------------------------
471 // CommandLineFlag
472 //    This represents a single flag, including its name, description,
473 //    default value, and current value.  Mostly this serves as a
474 //    struct, though it also knows how to register itself.
475 //       All CommandLineFlags are owned by a (exactly one)
476 //    FlagRegistry.  If you wish to modify fields in this class, you
477 //    should acquire the FlagRegistry lock for the registry that owns
478 //    this flag.
479 // --------------------------------------------------------------------
480 
481 class CommandLineFlag {
482  public:
483   // Note: we take over memory-ownership of current_val and default_val.
484   CommandLineFlag(const char* name, const char* help, const char* filename,
485                   FlagValue* current_val, FlagValue* default_val);
486   ~CommandLineFlag();
487 
name() const488   const char* name() const { return name_; }
help() const489   const char* help() const { return help_; }
filename() const490   const char* filename() const { return file_; }
491   const char* CleanFileName() const;  // nixes irrelevant prefix such as homedir
current_value() const492   string current_value() const { return current_->ToString(); }
default_value() const493   string default_value() const { return defvalue_->ToString(); }
type_name() const494   const char* type_name() const { return defvalue_->TypeName(); }
validate_function() const495   ValidateFnProto validate_function() const { return validate_fn_proto_; }
flag_ptr() const496   const void* flag_ptr() const { return current_->value_buffer_; }
497 
498   void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
499 
500   // If validate_fn_proto_ is non-NULL, calls it on value, returns result.
501   bool Validate(const FlagValue& value) const;
ValidateCurrent() const502   bool ValidateCurrent() const { return Validate(*current_); }
503 
504  private:
505   // for SetFlagLocked() and setting flags_by_ptr_
506   friend class FlagRegistry;
507   friend class GOOGLE_NAMESPACE::FlagSaverImpl;  // for cloning the values
508   // set validate_fn
509   friend bool AddFlagValidator(const void*, ValidateFnProto);
510 
511   // This copies all the non-const members: modified, processed, defvalue, etc.
512   void CopyFrom(const CommandLineFlag& src);
513 
514   void UpdateModifiedBit();
515 
516   const char* const name_;     // Flag name
517   const char* const help_;     // Help message
518   const char* const file_;     // Which file did this come from?
519   bool modified_;              // Set after default assignment?
520   FlagValue* defvalue_;        // Default value for flag
521   FlagValue* current_;         // Current value for flag
522   // This is a casted, 'generic' version of validate_fn, which actually
523   // takes a flag-value as an arg (void (*validate_fn)(bool), say).
524   // When we pass this to current_->Validate(), it will cast it back to
525   // the proper type.  This may be NULL to mean we have no validate_fn.
526   ValidateFnProto validate_fn_proto_;
527 
528   CommandLineFlag(const CommandLineFlag&);   // no copying!
529   void operator=(const CommandLineFlag&);
530 };
531 
CommandLineFlag(const char * name,const char * help,const char * filename,FlagValue * current_val,FlagValue * default_val)532 CommandLineFlag::CommandLineFlag(const char* name, const char* help,
533                                  const char* filename,
534                                  FlagValue* current_val, FlagValue* default_val)
535     : name_(name), help_(help), file_(filename), modified_(false),
536       defvalue_(default_val), current_(current_val), validate_fn_proto_(NULL) {
537 }
538 
~CommandLineFlag()539 CommandLineFlag::~CommandLineFlag() {
540   delete current_;
541   delete defvalue_;
542 }
543 
CleanFileName() const544 const char* CommandLineFlag::CleanFileName() const {
545   // Compute top-level directory & file that this appears in
546   // search full path backwards.
547   // Stop going backwards at kRootDir; and skip by the first slash.
548   static const char kRootDir[] = "";    // can set this to root directory,
549 
550   if (sizeof(kRootDir)-1 == 0)          // no prefix to strip
551     return filename();
552 
553   const char* clean_name = filename() + strlen(filename()) - 1;
554   while ( clean_name > filename() ) {
555     if (*clean_name == PATH_SEPARATOR) {
556       if (strncmp(clean_name, kRootDir, sizeof(kRootDir)-1) == 0) {
557         clean_name += sizeof(kRootDir)-1;    // past root-dir
558         break;
559       }
560     }
561     --clean_name;
562   }
563   while ( *clean_name == PATH_SEPARATOR ) ++clean_name;  // Skip any slashes
564   return clean_name;
565 }
566 
FillCommandLineFlagInfo(CommandLineFlagInfo * result)567 void CommandLineFlag::FillCommandLineFlagInfo(
568     CommandLineFlagInfo* result) {
569   result->name = name();
570   result->type = type_name();
571   result->description = help();
572   result->current_value = current_value();
573   result->default_value = default_value();
574   result->filename = CleanFileName();
575   UpdateModifiedBit();
576   result->is_default = !modified_;
577   result->has_validator_fn = validate_function() != NULL;
578   result->flag_ptr = flag_ptr();
579 }
580 
UpdateModifiedBit()581 void CommandLineFlag::UpdateModifiedBit() {
582   // Update the "modified" bit in case somebody bypassed the
583   // Flags API and wrote directly through the FLAGS_name variable.
584   if (!modified_ && !current_->Equal(*defvalue_)) {
585     modified_ = true;
586   }
587 }
588 
CopyFrom(const CommandLineFlag & src)589 void CommandLineFlag::CopyFrom(const CommandLineFlag& src) {
590   // Note we only copy the non-const members; others are fixed at construct time
591   if (modified_ != src.modified_) modified_ = src.modified_;
592   if (!current_->Equal(*src.current_)) current_->CopyFrom(*src.current_);
593   if (!defvalue_->Equal(*src.defvalue_)) defvalue_->CopyFrom(*src.defvalue_);
594   if (validate_fn_proto_ != src.validate_fn_proto_)
595     validate_fn_proto_ = src.validate_fn_proto_;
596 }
597 
Validate(const FlagValue & value) const598 bool CommandLineFlag::Validate(const FlagValue& value) const {
599 
600   if (validate_function() == NULL)
601     return true;
602   else
603     return value.Validate(name(), validate_function());
604 }
605 
606 
607 // --------------------------------------------------------------------
608 // FlagRegistry
609 //    A FlagRegistry singleton object holds all flag objects indexed
610 //    by their names so that if you know a flag's name (as a C
611 //    string), you can access or set it.  If the function is named
612 //    FooLocked(), you must own the registry lock before calling
613 //    the function; otherwise, you should *not* hold the lock, and
614 //    the function will acquire it itself if needed.
615 // --------------------------------------------------------------------
616 
617 struct StringCmp {  // Used by the FlagRegistry map class to compare char*'s
operator ()__anon2028b58c0111::StringCmp618   bool operator() (const char* s1, const char* s2) const {
619     return (strcmp(s1, s2) < 0);
620   }
621 };
622 
623 
624 class FlagRegistry {
625  public:
FlagRegistry()626   FlagRegistry() {
627   }
~FlagRegistry()628   ~FlagRegistry() {
629     // Not using STLDeleteElements as that resides in util and this
630     // class is base.
631     for (FlagMap::iterator p = flags_.begin(), e = flags_.end(); p != e; ++p) {
632       CommandLineFlag* flag = p->second;
633       delete flag;
634     }
635   }
636 
DeleteGlobalRegistry()637   static void DeleteGlobalRegistry() {
638     delete global_registry_;
639     global_registry_ = NULL;
640   }
641 
642   // Store a flag in this registry.  Takes ownership of the given pointer.
643   void RegisterFlag(CommandLineFlag* flag);
644 
Lock()645   void Lock() { lock_.Lock(); }
Unlock()646   void Unlock() { lock_.Unlock(); }
647 
648   // Returns the flag object for the specified name, or NULL if not found.
649   CommandLineFlag* FindFlagLocked(const char* name);
650 
651   // Returns the flag object whose current-value is stored at flag_ptr.
652   // That is, for whom current_->value_buffer_ == flag_ptr
653   CommandLineFlag* FindFlagViaPtrLocked(const void* flag_ptr);
654 
655   // A fancier form of FindFlag that works correctly if name is of the
656   // form flag=value.  In that case, we set key to point to flag, and
657   // modify v to point to the value (if present), and return the flag
658   // with the given name.  If the flag does not exist, returns NULL
659   // and sets error_message.
660   CommandLineFlag* SplitArgumentLocked(const char* argument,
661                                        string* key, const char** v,
662                                        string* error_message);
663 
664   // Set the value of a flag.  If the flag was successfully set to
665   // value, set msg to indicate the new flag-value, and return true.
666   // Otherwise, set msg to indicate the error, leave flag unchanged,
667   // and return false.  msg can be NULL.
668   bool SetFlagLocked(CommandLineFlag* flag, const char* value,
669                      FlagSettingMode set_mode, string* msg);
670 
671   static FlagRegistry* GlobalRegistry();   // returns a singleton registry
672 
673  private:
674   friend class GOOGLE_NAMESPACE::FlagSaverImpl;  // reads all the flags in order to copy them
675   friend class CommandLineFlagParser;    // for ValidateAllFlags
676   friend void GOOGLE_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
677 
678   // The map from name to flag, for FindFlagLocked().
679   typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
680   typedef FlagMap::iterator FlagIterator;
681   typedef FlagMap::const_iterator FlagConstIterator;
682   FlagMap flags_;
683 
684   // The map from current-value pointer to flag, fo FindFlagViaPtrLocked().
685   typedef map<const void*, CommandLineFlag*> FlagPtrMap;
686   FlagPtrMap flags_by_ptr_;
687 
688   static FlagRegistry* global_registry_;   // a singleton registry
689 
690   Mutex lock_;
691   static Mutex global_registry_lock_;
692 
693   static void InitGlobalRegistry();
694 
695   // Disallow
696   FlagRegistry(const FlagRegistry&);
697   FlagRegistry& operator=(const FlagRegistry&);
698 };
699 
700 class FlagRegistryLock {
701  public:
FlagRegistryLock(FlagRegistry * fr)702   explicit FlagRegistryLock(FlagRegistry* fr) : fr_(fr) { fr_->Lock(); }
~FlagRegistryLock()703   ~FlagRegistryLock() { fr_->Unlock(); }
704  private:
705   FlagRegistry *const fr_;
706 };
707 
708 
RegisterFlag(CommandLineFlag * flag)709 void FlagRegistry::RegisterFlag(CommandLineFlag* flag) {
710   Lock();
711   pair<FlagIterator, bool> ins =
712     flags_.insert(pair<const char*, CommandLineFlag*>(flag->name(), flag));
713   if (ins.second == false) {   // means the name was already in the map
714     if (strcmp(ins.first->second->filename(), flag->filename()) != 0) {
715       ReportError(DIE, "ERROR: flag '%s' was defined more than once "
716                   "(in files '%s' and '%s').\n",
717                   flag->name(),
718                   ins.first->second->filename(),
719                   flag->filename());
720     } else {
721       ReportError(DIE, "ERROR: something wrong with flag '%s' in file '%s'.  "
722                   "One possibility: file '%s' is being linked both statically "
723                   "and dynamically into this executable.\n",
724                   flag->name(),
725                   flag->filename(), flag->filename());
726     }
727   }
728   // Also add to the flags_by_ptr_ map.
729   flags_by_ptr_[flag->current_->value_buffer_] = flag;
730   Unlock();
731 }
732 
FindFlagLocked(const char * name)733 CommandLineFlag* FlagRegistry::FindFlagLocked(const char* name) {
734   FlagConstIterator i = flags_.find(name);
735   if (i == flags_.end()) {
736     return NULL;
737   } else {
738     return i->second;
739   }
740 }
741 
FindFlagViaPtrLocked(const void * flag_ptr)742 CommandLineFlag* FlagRegistry::FindFlagViaPtrLocked(const void* flag_ptr) {
743   FlagPtrMap::const_iterator i = flags_by_ptr_.find(flag_ptr);
744   if (i == flags_by_ptr_.end()) {
745     return NULL;
746   } else {
747     return i->second;
748   }
749 }
750 
SplitArgumentLocked(const char * arg,string * key,const char ** v,string * error_message)751 CommandLineFlag* FlagRegistry::SplitArgumentLocked(const char* arg,
752                                                    string* key,
753                                                    const char** v,
754                                                    string* error_message) {
755   // Find the flag object for this option
756   const char* flag_name;
757   const char* value = strchr(arg, '=');
758   if (value == NULL) {
759     key->assign(arg);
760     *v = NULL;
761   } else {
762     // Strip out the "=value" portion from arg
763     key->assign(arg, value-arg);
764     *v = ++value;    // advance past the '='
765   }
766   flag_name = key->c_str();
767 
768   CommandLineFlag* flag = FindFlagLocked(flag_name);
769 
770   if (flag == NULL) {
771     // If we can't find the flag-name, then we should return an error.
772     // The one exception is if 1) the flag-name is 'nox', 2) there
773     // exists a flag named 'x', and 3) 'x' is a boolean flag.
774     // In that case, we want to return flag 'x'.
775     if (!(flag_name[0] == 'n' && flag_name[1] == 'o')) {
776       // flag-name is not 'nox', so we're not in the exception case.
777       *error_message = StringPrintf("%sunknown command line flag '%s'\n",
778                                     kError, key->c_str());
779       return NULL;
780     }
781     flag = FindFlagLocked(flag_name+2);
782     if (flag == NULL) {
783       // No flag named 'x' exists, so we're not in the exception case.
784       *error_message = StringPrintf("%sunknown command line flag '%s'\n",
785                                     kError, key->c_str());
786       return NULL;
787     }
788     if (strcmp(flag->type_name(), "bool") != 0) {
789       // 'x' exists but is not boolean, so we're not in the exception case.
790       *error_message = StringPrintf(
791           "%sboolean value (%s) specified for %s command line flag\n",
792           kError, key->c_str(), flag->type_name());
793       return NULL;
794     }
795     // We're in the exception case!
796     // Make up a fake value to replace the "no" we stripped out
797     key->assign(flag_name+2);   // the name without the "no"
798     *v = "0";
799   }
800 
801   // Assign a value if this is a boolean flag
802   if (*v == NULL && strcmp(flag->type_name(), "bool") == 0) {
803     *v = "1";    // the --nox case was already handled, so this is the --x case
804   }
805 
806   return flag;
807 }
808 
TryParseLocked(const CommandLineFlag * flag,FlagValue * flag_value,const char * value,string * msg)809 bool TryParseLocked(const CommandLineFlag* flag, FlagValue* flag_value,
810                     const char* value, string* msg) {
811   // Use tenative_value, not flag_value, until we know value is valid.
812   FlagValue* tentative_value = flag_value->New();
813   if (!tentative_value->ParseFrom(value)) {
814     if (msg) {
815       StringAppendF(msg,
816                     "%sillegal value '%s' specified for %s flag '%s'\n",
817                     kError, value,
818                     flag->type_name(), flag->name());
819     }
820     delete tentative_value;
821     return false;
822   } else if (!flag->Validate(*tentative_value)) {
823     if (msg) {
824       StringAppendF(msg,
825           "%sfailed validation of new value '%s' for flag '%s'\n",
826           kError, tentative_value->ToString().c_str(),
827           flag->name());
828     }
829     delete tentative_value;
830     return false;
831   } else {
832     flag_value->CopyFrom(*tentative_value);
833     if (msg) {
834       StringAppendF(msg, "%s set to %s\n",
835                     flag->name(), flag_value->ToString().c_str());
836     }
837     delete tentative_value;
838     return true;
839   }
840 }
841 
SetFlagLocked(CommandLineFlag * flag,const char * value,FlagSettingMode set_mode,string * msg)842 bool FlagRegistry::SetFlagLocked(CommandLineFlag* flag,
843                                  const char* value,
844                                  FlagSettingMode set_mode,
845                                  string* msg) {
846   flag->UpdateModifiedBit();
847   switch (set_mode) {
848     case SET_FLAGS_VALUE: {
849       // set or modify the flag's value
850       if (!TryParseLocked(flag, flag->current_, value, msg))
851         return false;
852       flag->modified_ = true;
853       break;
854     }
855     case SET_FLAG_IF_DEFAULT: {
856       // set the flag's value, but only if it hasn't been set by someone else
857       if (!flag->modified_) {
858         if (!TryParseLocked(flag, flag->current_, value, msg))
859           return false;
860         flag->modified_ = true;
861       } else {
862         *msg = StringPrintf("%s set to %s",
863                             flag->name(), flag->current_value().c_str());
864       }
865       break;
866     }
867     case SET_FLAGS_DEFAULT: {
868       // modify the flag's default-value
869       if (!TryParseLocked(flag, flag->defvalue_, value, msg))
870         return false;
871       if (!flag->modified_) {
872         // Need to set both defvalue *and* current, in this case
873         TryParseLocked(flag, flag->current_, value, NULL);
874       }
875       break;
876     }
877     default: {
878       // unknown set_mode
879       assert(false);
880       return false;
881     }
882   }
883 
884   return true;
885 }
886 
887 // Get the singleton FlagRegistry object
888 FlagRegistry* FlagRegistry::global_registry_ = NULL;
889 Mutex FlagRegistry::global_registry_lock_(Mutex::LINKER_INITIALIZED);
890 
GlobalRegistry()891 FlagRegistry* FlagRegistry::GlobalRegistry() {
892   MutexLock acquire_lock(&global_registry_lock_);
893   if (!global_registry_) {
894     global_registry_ = new FlagRegistry;
895   }
896   return global_registry_;
897 }
898 
899 // --------------------------------------------------------------------
900 // CommandLineFlagParser
901 //    Parsing is done in two stages.  In the first, we go through
902 //    argv.  For every flag-like arg we can make sense of, we parse
903 //    it and set the appropriate FLAGS_* variable.  For every flag-
904 //    like arg we can't make sense of, we store it in a vector,
905 //    along with an explanation of the trouble.  In stage 2, we
906 //    handle the 'reporting' flags like --help and --mpm_version.
907 //    (This is via a call to HandleCommandLineHelpFlags(), in
908 //    gflags_reporting.cc.)
909 //    An optional stage 3 prints out the error messages.
910 //       This is a bit of a simplification.  For instance, --flagfile
911 //    is handled as soon as it's seen in stage 1, not in stage 2.
912 // --------------------------------------------------------------------
913 
914 class CommandLineFlagParser {
915  public:
916   // The argument is the flag-registry to register the parsed flags in
CommandLineFlagParser(FlagRegistry * reg)917   explicit CommandLineFlagParser(FlagRegistry* reg) : registry_(reg) {}
~CommandLineFlagParser()918   ~CommandLineFlagParser() {}
919 
920   // Stage 1: Every time this is called, it reads all flags in argv.
921   // However, it ignores all flags that have been successfully set
922   // before.  Typically this is only called once, so this 'reparsing'
923   // behavior isn't important.  It can be useful when trying to
924   // reparse after loading a dll, though.
925   uint32 ParseNewCommandLineFlags(int* argc, char*** argv, bool remove_flags);
926 
927   // Stage 2: print reporting info and exit, if requested.
928   // In gflags_reporting.cc:HandleCommandLineHelpFlags().
929 
930   // Stage 3: validate all the commandline flags that have validators
931   // registered.
932   void ValidateAllFlags();
933 
934   // Stage 4: report any errors and return true if any were found.
935   bool ReportErrors();
936 
937   // Set a particular command line option.  "newval" is a string
938   // describing the new value that the option has been set to.  If
939   // option_name does not specify a valid option name, or value is not
940   // a valid value for option_name, newval is empty.  Does recursive
941   // processing for --flagfile and --fromenv.  Returns the new value
942   // if everything went ok, or empty-string if not.  (Actually, the
943   // return-string could hold many flag/value pairs due to --flagfile.)
944   // NB: Must have called registry_->Lock() before calling this function.
945   string ProcessSingleOptionLocked(CommandLineFlag* flag,
946                                    const char* value,
947                                    FlagSettingMode set_mode);
948 
949   // Set a whole batch of command line options as specified by contentdata,
950   // which is in flagfile format (and probably has been read from a flagfile).
951   // Returns the new value if everything went ok, or empty-string if
952   // not.  (Actually, the return-string could hold many flag/value
953   // pairs due to --flagfile.)
954   // NB: Must have called registry_->Lock() before calling this function.
955   string ProcessOptionsFromStringLocked(const string& contentdata,
956                                         FlagSettingMode set_mode);
957 
958   // These are the 'recursive' flags, defined at the top of this file.
959   // Whenever we see these flags on the commandline, we must take action.
960   // These are called by ProcessSingleOptionLocked and, similarly, return
961   // new values if everything went ok, or the empty-string if not.
962   string ProcessFlagfileLocked(const string& flagval, FlagSettingMode set_mode);
963   // diff fromenv/tryfromenv
964   string ProcessFromenvLocked(const string& flagval, FlagSettingMode set_mode,
965                               bool errors_are_fatal);
966 
967  private:
968   FlagRegistry* const registry_;
969   map<string, string> error_flags_;      // map from name to error message
970   // This could be a set<string>, but we reuse the map to minimize the .o size
971   map<string, string> undefined_names_;  // --[flag] name was not registered
972 };
973 
974 
975 // Parse a list of (comma-separated) flags.
ParseFlagList(const char * value,vector<string> * flags)976 static void ParseFlagList(const char* value, vector<string>* flags) {
977   for (const char *p = value; p && *p; value = p) {
978     p = strchr(value, ',');
979     size_t len;
980     if (p) {
981       len = p - value;
982       p++;
983     } else {
984       len = strlen(value);
985     }
986 
987     if (len == 0)
988       ReportError(DIE, "ERROR: empty flaglist entry\n");
989     if (value[0] == '-')
990       ReportError(DIE, "ERROR: flag \"%*s\" begins with '-'\n", len, value);
991 
992     flags->push_back(string(value, len));
993   }
994 }
995 
996 // Snarf an entire file into a C++ string.  This is just so that we
997 // can do all the I/O in one place and not worry about it everywhere.
998 // Plus, it's convenient to have the whole file contents at hand.
999 // Adds a newline at the end of the file.
1000 #define PFATAL(s)  do { perror(s); gflags_exitfunc(1); } while (0)
1001 
ReadFileIntoString(const char * filename)1002 static string ReadFileIntoString(const char* filename) {
1003   const int kBufSize = 8092;
1004   char buffer[kBufSize];
1005   string s;
1006   FILE* fp = fopen(filename, "r");
1007   if (!fp)  PFATAL(filename);
1008   size_t n;
1009   while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
1010     if (ferror(fp))  PFATAL(filename);
1011     s.append(buffer, n);
1012   }
1013   fclose(fp);
1014   return s;
1015 }
1016 
ParseNewCommandLineFlags(int * argc,char *** argv,bool remove_flags)1017 uint32 CommandLineFlagParser::ParseNewCommandLineFlags(int* argc, char*** argv,
1018                                                        bool remove_flags) {
1019   const char *program_name = strrchr((*argv)[0], PATH_SEPARATOR);   // nix path
1020   program_name = (program_name == NULL ? (*argv)[0] : program_name+1);
1021 
1022   int first_nonopt = *argc;        // for non-options moved to the end
1023 
1024   registry_->Lock();
1025   for (int i = 1; i < first_nonopt; i++) {
1026     char* arg = (*argv)[i];
1027 
1028     // Like getopt(), we permute non-option flags to be at the end.
1029     if (arg[0] != '-' ||           // must be a program argument
1030         (arg[0] == '-' && arg[1] == '\0')) {  // "-" is an argument, not a flag
1031       memmove((*argv) + i, (*argv) + i+1, (*argc - (i+1)) * sizeof((*argv)[i]));
1032       (*argv)[*argc-1] = arg;      // we go last
1033       first_nonopt--;              // we've been pushed onto the stack
1034       i--;                         // to undo the i++ in the loop
1035       continue;
1036     }
1037 
1038     if (arg[0] == '-') arg++;      // allow leading '-'
1039     if (arg[0] == '-') arg++;      // or leading '--'
1040 
1041     // -- alone means what it does for GNU: stop options parsing
1042     if (*arg == '\0') {
1043       first_nonopt = i+1;
1044       break;
1045     }
1046 
1047     // Find the flag object for this option
1048     string key;
1049     const char* value;
1050     string error_message;
1051     CommandLineFlag* flag = registry_->SplitArgumentLocked(arg, &key, &value,
1052                                                            &error_message);
1053     if (flag == NULL) {
1054       undefined_names_[key] = "";    // value isn't actually used
1055       error_flags_[key] = error_message;
1056       continue;
1057     }
1058 
1059     if (value == NULL) {
1060       // Boolean options are always assigned a value by SplitArgumentLocked()
1061       assert(strcmp(flag->type_name(), "bool") != 0);
1062       if (i+1 >= first_nonopt) {
1063         // This flag needs a value, but there is nothing available
1064         error_flags_[key] = (string(kError) + "flag '" + (*argv)[i] + "'"
1065                              + " is missing its argument");
1066         if (flag->help() && flag->help()[0] > '\001') {
1067           // Be useful in case we have a non-stripped description.
1068           error_flags_[key] += string("; flag description: ") + flag->help();
1069         }
1070         error_flags_[key] += "\n";
1071         break;    // we treat this as an unrecoverable error
1072       } else {
1073         value = (*argv)[++i];                   // read next arg for value
1074 
1075         // Heuristic to detect the case where someone treats a string arg
1076         // like a bool:
1077         // --my_string_var --foo=bar
1078         // We look for a flag of string type, whose value begins with a
1079         // dash, and where the flag-name and value are separated by a
1080         // space rather than an '='.
1081         // To avoid false positives, we also require the word "true"
1082         // or "false" in the help string.  Without this, a valid usage
1083         // "-lat -30.5" would trigger the warning.  The common cases we
1084         // want to solve talk about true and false as values.
1085         if (value[0] == '-'
1086             && strcmp(flag->type_name(), "string") == 0
1087             && (strstr(flag->help(), "true")
1088                 || strstr(flag->help(), "false"))) {
1089           LOG(WARNING) << "Did you really mean to set flag '"
1090                        << flag->name() << "' to the value '"
1091                        << value << "'?";
1092         }
1093       }
1094     }
1095 
1096     // TODO(csilvers): only set a flag if we hadn't set it before here
1097     ProcessSingleOptionLocked(flag, value, SET_FLAGS_VALUE);
1098   }
1099   registry_->Unlock();
1100 
1101   if (remove_flags) {   // Fix up argc and argv by removing command line flags
1102     (*argv)[first_nonopt-1] = (*argv)[0];
1103     (*argv) += (first_nonopt-1);
1104     (*argc) -= (first_nonopt-1);
1105     first_nonopt = 1;   // because we still don't count argv[0]
1106   }
1107 
1108   logging_is_probably_set_up = true;   // because we've parsed --logdir, etc.
1109 
1110   return first_nonopt;
1111 }
1112 
ProcessFlagfileLocked(const string & flagval,FlagSettingMode set_mode)1113 string CommandLineFlagParser::ProcessFlagfileLocked(const string& flagval,
1114                                                     FlagSettingMode set_mode) {
1115   if (flagval.empty())
1116     return "";
1117 
1118   string msg;
1119   vector<string> filename_list;
1120   ParseFlagList(flagval.c_str(), &filename_list);  // take a list of filenames
1121   for (size_t i = 0; i < filename_list.size(); ++i) {
1122     const char* file = filename_list[i].c_str();
1123     msg += ProcessOptionsFromStringLocked(ReadFileIntoString(file), set_mode);
1124   }
1125   return msg;
1126 }
1127 
ProcessFromenvLocked(const string & flagval,FlagSettingMode set_mode,bool errors_are_fatal)1128 string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
1129                                                    FlagSettingMode set_mode,
1130                                                    bool errors_are_fatal) {
1131   if (flagval.empty())
1132     return "";
1133 
1134   string msg;
1135   vector<string> flaglist;
1136   ParseFlagList(flagval.c_str(), &flaglist);
1137 
1138   for (size_t i = 0; i < flaglist.size(); ++i) {
1139     const char* flagname = flaglist[i].c_str();
1140     CommandLineFlag* flag = registry_->FindFlagLocked(flagname);
1141     if (flag == NULL) {
1142       error_flags_[flagname] =
1143           StringPrintf("%sunknown command line flag '%s' "
1144                        "(via --fromenv or --tryfromenv)\n",
1145                        kError, flagname);
1146       undefined_names_[flagname] = "";
1147       continue;
1148     }
1149 
1150     const string envname = string("FLAGS_") + string(flagname);
1151     const char* envval = getenv(envname.c_str());
1152     if (!envval) {
1153       if (errors_are_fatal) {
1154         error_flags_[flagname] = (string(kError) + envname +
1155                                   " not found in environment\n");
1156       }
1157       continue;
1158     }
1159 
1160     // Avoid infinite recursion.
1161     if ((strcmp(envval, "fromenv") == 0) ||
1162         (strcmp(envval, "tryfromenv") == 0)) {
1163       error_flags_[flagname] =
1164           StringPrintf("%sinfinite recursion on environment flag '%s'\n",
1165                        kError, envval);
1166       continue;
1167     }
1168 
1169     msg += ProcessSingleOptionLocked(flag, envval, set_mode);
1170   }
1171   return msg;
1172 }
1173 
ProcessSingleOptionLocked(CommandLineFlag * flag,const char * value,FlagSettingMode set_mode)1174 string CommandLineFlagParser::ProcessSingleOptionLocked(
1175     CommandLineFlag* flag, const char* value, FlagSettingMode set_mode) {
1176   string msg;
1177   if (value && !registry_->SetFlagLocked(flag, value, set_mode, &msg)) {
1178     error_flags_[flag->name()] = msg;
1179     return "";
1180   }
1181 
1182   // The recursive flags, --flagfile and --fromenv and --tryfromenv,
1183   // must be dealt with as soon as they're seen.  They will emit
1184   // messages of their own.
1185   if (strcmp(flag->name(), "flagfile") == 0) {
1186     msg += ProcessFlagfileLocked(FLAGS_flagfile, set_mode);
1187 
1188   } else if (strcmp(flag->name(), "fromenv") == 0) {
1189     // last arg indicates envval-not-found is fatal (unlike in --tryfromenv)
1190     msg += ProcessFromenvLocked(FLAGS_fromenv, set_mode, true);
1191 
1192   } else if (strcmp(flag->name(), "tryfromenv") == 0) {
1193     msg += ProcessFromenvLocked(FLAGS_tryfromenv, set_mode, false);
1194   }
1195 
1196   return msg;
1197 }
1198 
ValidateAllFlags()1199 void CommandLineFlagParser::ValidateAllFlags() {
1200   FlagRegistryLock frl(registry_);
1201   for (FlagRegistry::FlagConstIterator i = registry_->flags_.begin();
1202        i != registry_->flags_.end(); ++i) {
1203     if (!i->second->ValidateCurrent()) {
1204       // only set a message if one isn't already there.  (If there's
1205       // an error message, our job is done, even if it's not exactly
1206       // the same error.)
1207       if (error_flags_[i->second->name()].empty())
1208         error_flags_[i->second->name()] =
1209             string(kError) + "--" + i->second->name() +
1210             " must be set on the commandline"
1211             " (default value fails validation)\n";
1212     }
1213   }
1214 }
1215 
ReportErrors()1216 bool CommandLineFlagParser::ReportErrors() {
1217   // error_flags_ indicates errors we saw while parsing.
1218   // But we ignore undefined-names if ok'ed by --undef_ok
1219   if (!FLAGS_undefok.empty()) {
1220     vector<string> flaglist;
1221     ParseFlagList(FLAGS_undefok.c_str(), &flaglist);
1222     for (size_t i = 0; i < flaglist.size(); ++i) {
1223       // We also deal with --no<flag>, in case the flagname was boolean
1224       const string no_version = string("no") + flaglist[i];
1225       if (undefined_names_.find(flaglist[i]) != undefined_names_.end()) {
1226         error_flags_[flaglist[i]] = "";    // clear the error message
1227       } else if (undefined_names_.find(no_version) != undefined_names_.end()) {
1228         error_flags_[no_version] = "";
1229       }
1230     }
1231   }
1232   // Likewise, if they decided to allow reparsing, all undefined-names
1233   // are ok; we just silently ignore them now, and hope that a future
1234   // parse will pick them up somehow.
1235   if (allow_command_line_reparsing) {
1236     for (map<string, string>::const_iterator it = undefined_names_.begin();
1237          it != undefined_names_.end();  ++it)
1238       error_flags_[it->first] = "";      // clear the error message
1239   }
1240 
1241   bool found_error = false;
1242   string error_message;
1243   for (map<string, string>::const_iterator it = error_flags_.begin();
1244        it != error_flags_.end(); ++it) {
1245     if (!it->second.empty()) {
1246       error_message.append(it->second.data(), it->second.size());
1247       found_error = true;
1248     }
1249   }
1250   if (found_error)
1251     ReportError(DO_NOT_DIE, "%s", error_message.c_str());
1252   return found_error;
1253 }
1254 
ProcessOptionsFromStringLocked(const string & contentdata,FlagSettingMode set_mode)1255 string CommandLineFlagParser::ProcessOptionsFromStringLocked(
1256     const string& contentdata, FlagSettingMode set_mode) {
1257   string retval;
1258   const char* flagfile_contents = contentdata.c_str();
1259   bool flags_are_relevant = true;   // set to false when filenames don't match
1260   bool in_filename_section = false;
1261 
1262   const char* line_end = flagfile_contents;
1263   // We read this file a line at a time.
1264   for (; line_end; flagfile_contents = line_end + 1) {
1265     while (*flagfile_contents && isspace(*flagfile_contents))
1266       ++flagfile_contents;
1267     line_end = strchr(flagfile_contents, '\n');
1268     size_t len = line_end ? line_end - flagfile_contents
1269                           : strlen(flagfile_contents);
1270     string line(flagfile_contents, len);
1271 
1272     // Each line can be one of four things:
1273     // 1) A comment line -- we skip it
1274     // 2) An empty line -- we skip it
1275     // 3) A list of filenames -- starts a new filenames+flags section
1276     // 4) A --flag=value line -- apply if previous filenames match
1277     if (line.empty() || line[0] == '#') {
1278       // comment or empty line; just ignore
1279 
1280     } else if (line[0] == '-') {    // flag
1281       in_filename_section = false;  // instead, it was a flag-line
1282       if (!flags_are_relevant)      // skip this flag; applies to someone else
1283         continue;
1284 
1285       const char* name_and_val = line.c_str() + 1;    // skip the leading -
1286       if (*name_and_val == '-')
1287         name_and_val++;                               // skip second - too
1288       string key;
1289       const char* value;
1290       string error_message;
1291       CommandLineFlag* flag = registry_->SplitArgumentLocked(name_and_val,
1292                                                              &key, &value,
1293                                                              &error_message);
1294       // By API, errors parsing flagfile lines are silently ignored.
1295       if (flag == NULL) {
1296         // "WARNING: flagname '" + key + "' not found\n"
1297       } else if (value == NULL) {
1298         // "WARNING: flagname '" + key + "' missing a value\n"
1299       } else {
1300         retval += ProcessSingleOptionLocked(flag, value, set_mode);
1301       }
1302 
1303     } else {                        // a filename!
1304       if (!in_filename_section) {   // start over: assume filenames don't match
1305         in_filename_section = true;
1306         flags_are_relevant = false;
1307       }
1308 
1309       // Split the line up at spaces into glob-patterns
1310       const char* space = line.c_str();   // just has to be non-NULL
1311       for (const char* word = line.c_str(); *space; word = space+1) {
1312         if (flags_are_relevant)     // we can stop as soon as we match
1313           break;
1314         space = strchr(word, ' ');
1315         if (space == NULL)
1316           space = word + strlen(word);
1317         const string glob(word, space - word);
1318         // We try matching both against the full argv0 and basename(argv0)
1319         if (glob == ProgramInvocationName()       // small optimization
1320             || glob == ProgramInvocationShortName()
1321 #ifdef HAVE_FNMATCH_H
1322             || fnmatch(glob.c_str(),
1323                        ProgramInvocationName(),
1324                        FNM_PATHNAME) == 0
1325             || fnmatch(glob.c_str(),
1326                        ProgramInvocationShortName(),
1327                        FNM_PATHNAME) == 0
1328 #endif
1329             ) {
1330           flags_are_relevant = true;
1331         }
1332       }
1333     }
1334   }
1335   return retval;
1336 }
1337 
1338 // --------------------------------------------------------------------
1339 // GetFromEnv()
1340 // AddFlagValidator()
1341 //    These are helper functions for routines like BoolFromEnv() and
1342 //    RegisterFlagValidator, defined below.  They're defined here so
1343 //    they can live in the unnamed namespace (which makes friendship
1344 //    declarations for these classes possible).
1345 // --------------------------------------------------------------------
1346 
1347 template<typename T>
GetFromEnv(const char * varname,const char * type,T dflt)1348 T GetFromEnv(const char *varname, const char* type, T dflt) {
1349   const char* const valstr = getenv(varname);
1350   if (!valstr)
1351     return dflt;
1352   FlagValue ifv(new T, type, true);
1353   if (!ifv.ParseFrom(valstr))
1354     ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
1355                 varname, valstr);
1356   return OTHER_VALUE_AS(ifv, T);
1357 }
1358 
AddFlagValidator(const void * flag_ptr,ValidateFnProto validate_fn_proto)1359 bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
1360   // We want a lock around this routine, in case two threads try to
1361   // add a validator (hopefully the same one!) at once.  We could use
1362   // our own thread, but we need to loook at the registry anyway, so
1363   // we just steal that one.
1364   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1365   FlagRegistryLock frl(registry);
1366   // First, find the flag whose current-flag storage is 'flag'.
1367   // This is the CommandLineFlag whose current_->value_buffer_ == flag
1368   CommandLineFlag* flag = registry->FindFlagViaPtrLocked(flag_ptr);
1369   if (!flag) {
1370     LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag pointer "
1371                  << flag_ptr << ": no flag found at that address";
1372     return false;
1373   } else if (validate_fn_proto == flag->validate_function()) {
1374     return true;    // ok to register the same function over and over again
1375   } else if (validate_fn_proto != NULL && flag->validate_function() != NULL) {
1376     LOG(WARNING) << "Ignoring RegisterValidateFunction() for flag '"
1377                  << flag->name() << "': validate-fn already registered";
1378     return false;
1379   } else {
1380     flag->validate_fn_proto_ = validate_fn_proto;
1381     return true;
1382   }
1383 }
1384 
1385 }  // end unnamed namespaces
1386 
1387 
1388 // Now define the functions that are exported via the .h file
1389 
1390 // --------------------------------------------------------------------
1391 // FlagRegisterer
1392 //    This class exists merely to have a global constructor (the
1393 //    kind that runs before main(), that goes an initializes each
1394 //    flag that's been declared.  Note that it's very important we
1395 //    don't have a destructor that deletes flag_, because that would
1396 //    cause us to delete current_storage/defvalue_storage as well,
1397 //    which can cause a crash if anything tries to access the flag
1398 //    values in a global destructor.
1399 // --------------------------------------------------------------------
1400 
FlagRegisterer(const char * name,const char * type,const char * help,const char * filename,void * current_storage,void * defvalue_storage)1401 FlagRegisterer::FlagRegisterer(const char* name, const char* type,
1402                                const char* help, const char* filename,
1403                                void* current_storage, void* defvalue_storage) {
1404   if (help == NULL)
1405     help = "";
1406   // FlagValue expects the type-name to not include any namespace
1407   // components, so we get rid of those, if any.
1408   if (strchr(type, ':'))
1409     type = strrchr(type, ':') + 1;
1410   FlagValue* current = new FlagValue(current_storage, type, false);
1411   FlagValue* defvalue = new FlagValue(defvalue_storage, type, false);
1412   // Importantly, flag_ will never be deleted, so storage is always good.
1413   CommandLineFlag* flag = new CommandLineFlag(name, help, filename,
1414                                               current, defvalue);
1415   FlagRegistry::GlobalRegistry()->RegisterFlag(flag);   // default registry
1416 }
1417 
1418 // --------------------------------------------------------------------
1419 // GetAllFlags()
1420 //    The main way the FlagRegistry class exposes its data.  This
1421 //    returns, as strings, all the info about all the flags in
1422 //    the main registry, sorted first by filename they are defined
1423 //    in, and then by flagname.
1424 // --------------------------------------------------------------------
1425 
1426 struct FilenameFlagnameCmp {
operator ()FilenameFlagnameCmp1427   bool operator()(const CommandLineFlagInfo& a,
1428                   const CommandLineFlagInfo& b) const {
1429     int cmp = strcmp(a.filename.c_str(), b.filename.c_str());
1430     if (cmp == 0)
1431       cmp = strcmp(a.name.c_str(), b.name.c_str());  // secondary sort key
1432     return cmp < 0;
1433   }
1434 };
1435 
GetAllFlags(vector<CommandLineFlagInfo> * OUTPUT)1436 void GetAllFlags(vector<CommandLineFlagInfo>* OUTPUT) {
1437   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1438   registry->Lock();
1439   for (FlagRegistry::FlagConstIterator i = registry->flags_.begin();
1440        i != registry->flags_.end(); ++i) {
1441     CommandLineFlagInfo fi;
1442     i->second->FillCommandLineFlagInfo(&fi);
1443     OUTPUT->push_back(fi);
1444   }
1445   registry->Unlock();
1446   // Now sort the flags, first by filename they occur in, then alphabetically
1447   sort(OUTPUT->begin(), OUTPUT->end(), FilenameFlagnameCmp());
1448 }
1449 
1450 // --------------------------------------------------------------------
1451 // SetArgv()
1452 // GetArgvs()
1453 // GetArgv()
1454 // GetArgv0()
1455 // ProgramInvocationName()
1456 // ProgramInvocationShortName()
1457 // SetUsageMessage()
1458 // ProgramUsage()
1459 //    Functions to set and get argv.  Typically the setter is called
1460 //    by ParseCommandLineFlags.  Also can get the ProgramUsage string,
1461 //    set by SetUsageMessage.
1462 // --------------------------------------------------------------------
1463 
1464 // These values are not protected by a Mutex because they are normally
1465 // set only once during program startup.
1466 static const char* argv0 = "UNKNOWN";      // just the program name
1467 static const char* cmdline = "";           // the entire command-line
1468 static vector<string> argvs;
1469 static uint32 argv_sum = 0;
1470 static const char* program_usage = NULL;
1471 
SetArgv(int argc,const char ** argv)1472 void SetArgv(int argc, const char** argv) {
1473   static bool called_set_argv = false;
1474   if (called_set_argv)         // we already have an argv for you
1475     return;
1476 
1477   called_set_argv = true;
1478 
1479   assert(argc > 0);            // every program has at least a progname
1480   argv0 = strdup(argv[0]);     // small memory leak, but fn only called once
1481   assert(argv0);
1482 
1483   string cmdline_string;       // easier than doing strcats
1484   for (int i = 0; i < argc; i++) {
1485     if (i != 0) {
1486       cmdline_string += " ";
1487     }
1488     cmdline_string += argv[i];
1489     argvs.push_back(argv[i]);
1490   }
1491   cmdline = strdup(cmdline_string.c_str());  // another small memory leak
1492   assert(cmdline);
1493 
1494   // Compute a simple sum of all the chars in argv
1495   for (const char* c = cmdline; *c; c++)
1496     argv_sum += *c;
1497 }
1498 
GetArgvs()1499 const vector<string>& GetArgvs() { return argvs; }
GetArgv()1500 const char* GetArgv()            { return cmdline; }
GetArgv0()1501 const char* GetArgv0()           { return argv0; }
GetArgvSum()1502 uint32 GetArgvSum()              { return argv_sum; }
ProgramInvocationName()1503 const char* ProgramInvocationName() {             // like the GNU libc fn
1504   return GetArgv0();
1505 }
ProgramInvocationShortName()1506 const char* ProgramInvocationShortName() {        // like the GNU libc fn
1507   const char* slash = strrchr(argv0, '/');
1508 #ifdef OS_WINDOWS
1509   if (!slash)  slash = strrchr(argv0, '\\');
1510 #endif
1511   return slash ? slash + 1 : argv0;
1512 }
1513 
SetUsageMessage(const string & usage)1514 void SetUsageMessage(const string& usage) {
1515   if (program_usage != NULL)
1516     ReportError(DIE, "ERROR: SetUsageMessage() called twice\n");
1517   program_usage = strdup(usage.c_str());      // small memory leak
1518 }
1519 
ProgramUsage()1520 const char* ProgramUsage() {
1521   if (program_usage) {
1522     return program_usage;
1523   }
1524   return "Warning: SetUsageMessage() never called";
1525 }
1526 
1527 // --------------------------------------------------------------------
1528 // SetVersionString()
1529 // VersionString()
1530 // --------------------------------------------------------------------
1531 
1532 static const char* version_string = NULL;
1533 
SetVersionString(const string & version)1534 void SetVersionString(const string& version) {
1535   if (version_string != NULL)
1536     ReportError(DIE, "ERROR: SetVersionString() called twice\n");
1537   version_string = strdup(version.c_str());   // small memory leak
1538 }
1539 
VersionString()1540 const char* VersionString() {
1541   return version_string ? version_string : "";
1542 }
1543 
1544 
1545 // --------------------------------------------------------------------
1546 // GetCommandLineOption()
1547 // GetCommandLineFlagInfo()
1548 // GetCommandLineFlagInfoOrDie()
1549 // SetCommandLineOption()
1550 // SetCommandLineOptionWithMode()
1551 //    The programmatic way to set a flag's value, using a string
1552 //    for its name rather than the variable itself (that is,
1553 //    SetCommandLineOption("foo", x) rather than FLAGS_foo = x).
1554 //    There's also a bit more flexibility here due to the various
1555 //    set-modes, but typically these are used when you only have
1556 //    that flag's name as a string, perhaps at runtime.
1557 //    All of these work on the default, global registry.
1558 //       For GetCommandLineOption, return false if no such flag
1559 //    is known, true otherwise.  We clear "value" if a suitable
1560 //    flag is found.
1561 // --------------------------------------------------------------------
1562 
1563 
GetCommandLineOption(const char * name,string * value)1564 bool GetCommandLineOption(const char* name, string* value) {
1565   if (NULL == name)
1566     return false;
1567   assert(value);
1568 
1569   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1570   FlagRegistryLock frl(registry);
1571   CommandLineFlag* flag = registry->FindFlagLocked(name);
1572   if (flag == NULL) {
1573     return false;
1574   } else {
1575     *value = flag->current_value();
1576     return true;
1577   }
1578 }
1579 
GetCommandLineFlagInfo(const char * name,CommandLineFlagInfo * OUTPUT)1580 bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT) {
1581   if (NULL == name) return false;
1582   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1583   FlagRegistryLock frl(registry);
1584   CommandLineFlag* flag = registry->FindFlagLocked(name);
1585   if (flag == NULL) {
1586     return false;
1587   } else {
1588     assert(OUTPUT);
1589     flag->FillCommandLineFlagInfo(OUTPUT);
1590     return true;
1591   }
1592 }
1593 
GetCommandLineFlagInfoOrDie(const char * name)1594 CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) {
1595   CommandLineFlagInfo info;
1596   if (!GetCommandLineFlagInfo(name, &info)) {
1597     fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exist\n", name);
1598     gflags_exitfunc(1);    // almost certainly gflags_exitfunc()
1599   }
1600   return info;
1601 }
1602 
SetCommandLineOptionWithMode(const char * name,const char * value,FlagSettingMode set_mode)1603 string SetCommandLineOptionWithMode(const char* name, const char* value,
1604                                     FlagSettingMode set_mode) {
1605   string result;
1606   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1607   FlagRegistryLock frl(registry);
1608   CommandLineFlag* flag = registry->FindFlagLocked(name);
1609   if (flag) {
1610     CommandLineFlagParser parser(registry);
1611     result = parser.ProcessSingleOptionLocked(flag, value, set_mode);
1612     if (!result.empty()) {   // in the error case, we've already logged
1613       // Could consider logging this change
1614     }
1615   }
1616   // The API of this function is that we return empty string on error
1617   return result;
1618 }
1619 
SetCommandLineOption(const char * name,const char * value)1620 string SetCommandLineOption(const char* name, const char* value) {
1621   return SetCommandLineOptionWithMode(name, value, SET_FLAGS_VALUE);
1622 }
1623 
1624 // --------------------------------------------------------------------
1625 // FlagSaver
1626 // FlagSaverImpl
1627 //    This class stores the states of all flags at construct time,
1628 //    and restores all flags to that state at destruct time.
1629 //    Its major implementation challenge is that it never modifies
1630 //    pointers in the 'main' registry, so global FLAG_* vars always
1631 //    point to the right place.
1632 // --------------------------------------------------------------------
1633 
1634 class FlagSaverImpl {
1635  public:
1636   // Constructs an empty FlagSaverImpl object.
FlagSaverImpl(FlagRegistry * main_registry)1637   explicit FlagSaverImpl(FlagRegistry* main_registry)
1638       : main_registry_(main_registry) { }
~FlagSaverImpl()1639   ~FlagSaverImpl() {
1640     // reclaim memory from each of our CommandLineFlags
1641     vector<CommandLineFlag*>::const_iterator it;
1642     for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it)
1643       delete *it;
1644   }
1645 
1646   // Saves the flag states from the flag registry into this object.
1647   // It's an error to call this more than once.
1648   // Must be called when the registry mutex is not held.
SaveFromRegistry()1649   void SaveFromRegistry() {
1650     FlagRegistryLock frl(main_registry_);
1651     assert(backup_registry_.empty());   // call only once!
1652     for (FlagRegistry::FlagConstIterator it = main_registry_->flags_.begin();
1653          it != main_registry_->flags_.end();
1654          ++it) {
1655       const CommandLineFlag* main = it->second;
1656       // Sets up all the const variables in backup correctly
1657       CommandLineFlag* backup = new CommandLineFlag(
1658           main->name(), main->help(), main->filename(),
1659           main->current_->New(), main->defvalue_->New());
1660       // Sets up all the non-const variables in backup correctly
1661       backup->CopyFrom(*main);
1662       backup_registry_.push_back(backup);   // add it to a convenient list
1663     }
1664   }
1665 
1666   // Restores the saved flag states into the flag registry.  We
1667   // assume no flags were added or deleted from the registry since
1668   // the SaveFromRegistry; if they were, that's trouble!  Must be
1669   // called when the registry mutex is not held.
RestoreToRegistry()1670   void RestoreToRegistry() {
1671     FlagRegistryLock frl(main_registry_);
1672     vector<CommandLineFlag*>::const_iterator it;
1673     for (it = backup_registry_.begin(); it != backup_registry_.end(); ++it) {
1674       CommandLineFlag* main = main_registry_->FindFlagLocked((*it)->name());
1675       if (main != NULL) {       // if NULL, flag got deleted from registry(!)
1676         main->CopyFrom(**it);
1677       }
1678     }
1679   }
1680 
1681  private:
1682   FlagRegistry* const main_registry_;
1683   vector<CommandLineFlag*> backup_registry_;
1684 
1685   FlagSaverImpl(const FlagSaverImpl&);  // no copying!
1686   void operator=(const FlagSaverImpl&);
1687 };
1688 
FlagSaver()1689 FlagSaver::FlagSaver()
1690     : impl_(new FlagSaverImpl(FlagRegistry::GlobalRegistry())) {
1691   impl_->SaveFromRegistry();
1692 }
1693 
~FlagSaver()1694 FlagSaver::~FlagSaver() {
1695   impl_->RestoreToRegistry();
1696   delete impl_;
1697 }
1698 
1699 
1700 // --------------------------------------------------------------------
1701 // CommandlineFlagsIntoString()
1702 // ReadFlagsFromString()
1703 // AppendFlagsIntoFile()
1704 // ReadFromFlagsFile()
1705 //    These are mostly-deprecated routines that stick the
1706 //    commandline flags into a file/string and read them back
1707 //    out again.  I can see a use for CommandlineFlagsIntoString,
1708 //    for creating a flagfile, but the rest don't seem that useful
1709 //    -- some, I think, are a poor-man's attempt at FlagSaver --
1710 //    and are included only until we can delete them from callers.
1711 //    Note they don't save --flagfile flags (though they do save
1712 //    the result of having called the flagfile, of course).
1713 // --------------------------------------------------------------------
1714 
TheseCommandlineFlagsIntoString(const vector<CommandLineFlagInfo> & flags)1715 static string TheseCommandlineFlagsIntoString(
1716     const vector<CommandLineFlagInfo>& flags) {
1717   vector<CommandLineFlagInfo>::const_iterator i;
1718 
1719   size_t retval_space = 0;
1720   for (i = flags.begin(); i != flags.end(); ++i) {
1721     // An (over)estimate of how much space it will take to print this flag
1722     retval_space += i->name.length() + i->current_value.length() + 5;
1723   }
1724 
1725   string retval;
1726   retval.reserve(retval_space);
1727   for (i = flags.begin(); i != flags.end(); ++i) {
1728     retval += "--";
1729     retval += i->name;
1730     retval += "=";
1731     retval += i->current_value;
1732     retval += "\n";
1733   }
1734   return retval;
1735 }
1736 
CommandlineFlagsIntoString()1737 string CommandlineFlagsIntoString() {
1738   vector<CommandLineFlagInfo> sorted_flags;
1739   GetAllFlags(&sorted_flags);
1740   return TheseCommandlineFlagsIntoString(sorted_flags);
1741 }
1742 
ReadFlagsFromString(const string & flagfilecontents,const char *,bool errors_are_fatal)1743 bool ReadFlagsFromString(const string& flagfilecontents,
1744                          const char* /*prog_name*/,  // TODO(csilvers): nix this
1745                          bool errors_are_fatal) {
1746   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1747   FlagSaverImpl saved_states(registry);
1748   saved_states.SaveFromRegistry();
1749 
1750   CommandLineFlagParser parser(registry);
1751   registry->Lock();
1752   parser.ProcessOptionsFromStringLocked(flagfilecontents, SET_FLAGS_VALUE);
1753   registry->Unlock();
1754   // Should we handle --help and such when reading flags from a string?  Sure.
1755   HandleCommandLineHelpFlags();
1756   if (parser.ReportErrors()) {
1757     // Error.  Restore all global flags to their previous values.
1758     if (errors_are_fatal)
1759       gflags_exitfunc(1);
1760     saved_states.RestoreToRegistry();
1761     return false;
1762   }
1763   return true;
1764 }
1765 
1766 // TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
AppendFlagsIntoFile(const string & filename,const char * prog_name)1767 bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
1768   FILE *fp = fopen(filename.c_str(), "a");
1769   if (!fp) {
1770     return false;
1771   }
1772 
1773   if (prog_name)
1774     fprintf(fp, "%s\n", prog_name);
1775 
1776   vector<CommandLineFlagInfo> flags;
1777   GetAllFlags(&flags);
1778   // But we don't want --flagfile, which leads to weird recursion issues
1779   vector<CommandLineFlagInfo>::iterator i;
1780   for (i = flags.begin(); i != flags.end(); ++i) {
1781     if (strcmp(i->name.c_str(), "flagfile") == 0) {
1782       flags.erase(i);
1783       break;
1784     }
1785   }
1786   fprintf(fp, "%s", TheseCommandlineFlagsIntoString(flags).c_str());
1787 
1788   fclose(fp);
1789   return true;
1790 }
1791 
ReadFromFlagsFile(const string & filename,const char * prog_name,bool errors_are_fatal)1792 bool ReadFromFlagsFile(const string& filename, const char* prog_name,
1793                        bool errors_are_fatal) {
1794   return ReadFlagsFromString(ReadFileIntoString(filename.c_str()),
1795                              prog_name, errors_are_fatal);
1796 }
1797 
1798 
1799 // --------------------------------------------------------------------
1800 // BoolFromEnv()
1801 // Int32FromEnv()
1802 // Int64FromEnv()
1803 // Uint64FromEnv()
1804 // DoubleFromEnv()
1805 // StringFromEnv()
1806 //    Reads the value from the environment and returns it.
1807 //    We use an FlagValue to make the parsing easy.
1808 //    Example usage:
1809 //       DEFINE_bool(myflag, BoolFromEnv("MYFLAG_DEFAULT", false), "whatever");
1810 // --------------------------------------------------------------------
1811 
BoolFromEnv(const char * v,bool dflt)1812 bool BoolFromEnv(const char *v, bool dflt) {
1813   return GetFromEnv(v, "bool", dflt);
1814 }
Int32FromEnv(const char * v,int32 dflt)1815 int32 Int32FromEnv(const char *v, int32 dflt) {
1816   return GetFromEnv(v, "int32", dflt);
1817 }
Int64FromEnv(const char * v,int64 dflt)1818 int64 Int64FromEnv(const char *v, int64 dflt)    {
1819   return GetFromEnv(v, "int64", dflt);
1820 }
Uint64FromEnv(const char * v,uint64 dflt)1821 uint64 Uint64FromEnv(const char *v, uint64 dflt) {
1822   return GetFromEnv(v, "uint64", dflt);
1823 }
DoubleFromEnv(const char * v,double dflt)1824 double DoubleFromEnv(const char *v, double dflt) {
1825   return GetFromEnv(v, "double", dflt);
1826 }
StringFromEnv(const char * varname,const char * dflt)1827 const char *StringFromEnv(const char *varname, const char *dflt) {
1828   const char* const val = getenv(varname);
1829   return val ? val : dflt;
1830 }
1831 
1832 
1833 // --------------------------------------------------------------------
1834 // RegisterFlagValidator()
1835 //    RegisterFlagValidator() is the function that clients use to
1836 //    'decorate' a flag with a validation function.  Once this is
1837 //    done, every time the flag is set (including when the flag
1838 //    is parsed from argv), the validator-function is called.
1839 //       These functions return true if the validator was added
1840 //    successfully, or false if not: the flag already has a validator,
1841 //    (only one allowed per flag), the 1st arg isn't a flag, etc.
1842 //       This function is not thread-safe.
1843 // --------------------------------------------------------------------
1844 
RegisterFlagValidator(const bool * flag,bool (* validate_fn)(const char *,bool))1845 bool RegisterFlagValidator(const bool* flag,
1846                            bool (*validate_fn)(const char*, bool)) {
1847   return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
1848 }
RegisterFlagValidator(const int32 * flag,bool (* validate_fn)(const char *,int32))1849 bool RegisterFlagValidator(const int32* flag,
1850                            bool (*validate_fn)(const char*, int32)) {
1851   return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
1852 }
RegisterFlagValidator(const int64 * flag,bool (* validate_fn)(const char *,int64))1853 bool RegisterFlagValidator(const int64* flag,
1854                            bool (*validate_fn)(const char*, int64)) {
1855   return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
1856 }
RegisterFlagValidator(const uint64 * flag,bool (* validate_fn)(const char *,uint64))1857 bool RegisterFlagValidator(const uint64* flag,
1858                            bool (*validate_fn)(const char*, uint64)) {
1859   return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
1860 }
RegisterFlagValidator(const double * flag,bool (* validate_fn)(const char *,double))1861 bool RegisterFlagValidator(const double* flag,
1862                            bool (*validate_fn)(const char*, double)) {
1863   return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
1864 }
RegisterFlagValidator(const string * flag,bool (* validate_fn)(const char *,const string &))1865 bool RegisterFlagValidator(const string* flag,
1866                            bool (*validate_fn)(const char*, const string&)) {
1867   return AddFlagValidator(flag, reinterpret_cast<ValidateFnProto>(validate_fn));
1868 }
1869 
1870 
1871 // --------------------------------------------------------------------
1872 // ParseCommandLineFlags()
1873 // ParseCommandLineNonHelpFlags()
1874 // HandleCommandLineHelpFlags()
1875 //    This is the main function called from main(), to actually
1876 //    parse the commandline.  It modifies argc and argv as described
1877 //    at the top of gflags.h.  You can also divide this
1878 //    function into two parts, if you want to do work between
1879 //    the parsing of the flags and the printing of any help output.
1880 // --------------------------------------------------------------------
1881 
ParseCommandLineFlagsInternal(int * argc,char *** argv,bool remove_flags,bool do_report)1882 static uint32 ParseCommandLineFlagsInternal(int* argc, char*** argv,
1883                                             bool remove_flags, bool do_report) {
1884   SetArgv(*argc, const_cast<const char**>(*argv));    // save it for later
1885 
1886   FlagRegistry* const registry = FlagRegistry::GlobalRegistry();
1887   CommandLineFlagParser parser(registry);
1888 
1889   // When we parse the commandline flags, we'll handle --flagfile,
1890   // --tryfromenv, etc. as we see them (since flag-evaluation order
1891   // may be important).  But sometimes apps set FLAGS_tryfromenv/etc.
1892   // manually before calling ParseCommandLineFlags.  We want to evaluate
1893   // those too, as if they were the first flags on the commandline.
1894   registry->Lock();
1895   parser.ProcessFlagfileLocked(FLAGS_flagfile, SET_FLAGS_VALUE);
1896   // Last arg here indicates whether flag-not-found is a fatal error or not
1897   parser.ProcessFromenvLocked(FLAGS_fromenv, SET_FLAGS_VALUE, true);
1898   parser.ProcessFromenvLocked(FLAGS_tryfromenv, SET_FLAGS_VALUE, false);
1899   registry->Unlock();
1900 
1901   // Now get the flags specified on the commandline
1902   const int r = parser.ParseNewCommandLineFlags(argc, argv, remove_flags);
1903 
1904   if (do_report)
1905     HandleCommandLineHelpFlags();   // may cause us to exit on --help, etc.
1906 
1907   // See if any of the unset flags fail their validation checks
1908   parser.ValidateAllFlags();
1909 
1910   if (parser.ReportErrors())        // may cause us to exit on illegal flags
1911     gflags_exitfunc(1);
1912   return r;
1913 }
1914 
ParseCommandLineFlags(int * argc,char *** argv,bool remove_flags)1915 uint32 ParseCommandLineFlags(int* argc, char*** argv, bool remove_flags) {
1916   return ParseCommandLineFlagsInternal(argc, argv, remove_flags, true);
1917 }
1918 
ParseCommandLineNonHelpFlags(int * argc,char *** argv,bool remove_flags)1919 uint32 ParseCommandLineNonHelpFlags(int* argc, char*** argv,
1920                                     bool remove_flags) {
1921   return ParseCommandLineFlagsInternal(argc, argv, remove_flags, false);
1922 }
1923 
1924 // --------------------------------------------------------------------
1925 // AllowCommandLineReparsing()
1926 // ReparseCommandLineNonHelpFlags()
1927 //    This is most useful for shared libraries.  The idea is if
1928 //    a flag is defined in a shared library that is dlopen'ed
1929 //    sometime after main(), you can ParseCommandLineFlags before
1930 //    the dlopen, then ReparseCommandLineNonHelpFlags() after the
1931 //    dlopen, to get the new flags.  But you have to explicitly
1932 //    Allow() it; otherwise, you get the normal default behavior
1933 //    of unrecognized flags calling a fatal error.
1934 // TODO(csilvers): this isn't used.  Just delete it?
1935 // --------------------------------------------------------------------
1936 
AllowCommandLineReparsing()1937 void AllowCommandLineReparsing() {
1938   allow_command_line_reparsing = true;
1939 }
1940 
ReparseCommandLineNonHelpFlags()1941 void ReparseCommandLineNonHelpFlags() {
1942   // We make a copy of argc and argv to pass in
1943   const vector<string>& argvs = GetArgvs();
1944   int tmp_argc = static_cast<int>(argvs.size());
1945   char** tmp_argv = new char* [tmp_argc + 1];
1946   for (int i = 0; i < tmp_argc; ++i)
1947     tmp_argv[i] = strdup(argvs[i].c_str());   // TODO(csilvers): don't dup
1948 
1949   ParseCommandLineNonHelpFlags(&tmp_argc, &tmp_argv, false);
1950 
1951   for (int i = 0; i < tmp_argc; ++i)
1952     free(tmp_argv[i]);
1953   delete[] tmp_argv;
1954 }
1955 
ShutDownCommandLineFlags()1956 void ShutDownCommandLineFlags() {
1957   FlagRegistry::DeleteGlobalRegistry();
1958 }
1959 
1960 _END_GOOGLE_NAMESPACE_
1961