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