Newer
Older
// Copyright (c) 1999, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Revamped and reorganized by Craig Silverstein
//
// This file contains the implementation of all our command line flags
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
// stuff. Here's how everything fits together
//
// * FlagRegistry owns CommandLineFlags owns FlagValue.
// * FlagSaver holds a FlagRegistry (saves it at construct time,
// restores it at destroy time).
// * CommandLineFlagParser lives outside that hierarchy, but works on
// CommandLineFlags (modifying the FlagValues).
// * Free functions like SetCommandLineOption() work via one of the
// above (such as CommandLineFlagParser).
//
// In more detail:
//
// -- The main classes that hold flag data:
//
// FlagValue holds the current value of a flag. It's
// pseudo-templatized: every operation on a FlagValue is typed. It
// also deals with storage-lifetime issues (so flag values don't go
// away in a destructor), which is why we need a whole class to hold a
// variable's value.
//
// CommandLineFlag is all the information about a single command-line
// flag. It has a FlagValue for the flag's current value, but also
// the flag's name, type, etc.
//
// FlagRegistry is a collection of CommandLineFlags. There's the
// global registry, which is where flags defined via DEFINE_foo()
// live. But it's possible to define your own flag, manually, in a
// different registry you create. (In practice, multiple registries
// are used only by FlagSaver).
//
// A given FlagValue is owned by exactly one CommandLineFlag. A given
// CommandLineFlag is owned by exactly one FlagRegistry. FlagRegistry
// has a lock; any operation that writes to a FlagValue or
// CommandLineFlag owned by that registry must acquire the
// FlagRegistry lock before doing so.
//
// --- Some other classes and free functions:
//
// CommandLineFlagInfo is a client-exposed version of CommandLineFlag.
// Once it's instantiated, it has no dependencies or relationships
// with any other part of this file.
//
// FlagRegisterer is the helper class used by the DEFINE_* macros to
// allow work to be done at global initialization time.
//
// CommandLineFlagParser is the class that reads from the commandline
// and instantiates flag values based on that. It needs to poke into
// the innards of the FlagValue->CommandLineFlag->FlagRegistry class
// hierarchy to do that. It's careful to acquire the FlagRegistry
// lock before doing any writing or other non-const actions.
//
// GetCommandLineOption is just a hook into registry routines to
// retrieve a flag based on its name. SetCommandLineOption, on the
// other hand, hooks into CommandLineFlagParser. Other API functions
// are, similarly, mostly hooks into the functionality described above.
// This comes first to ensure we define __STDC_FORMAT_MACROS in time.
#include <config.h>
#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1 // gcc requires this to get PRId64, etc.
#endif
#include <gflags/gflags.h>
#include <assert.h>
#ifdef HAVE_FNMATCH_H
# include <fnmatch.h>
#endif
#include <stdarg.h> // For va_list and related operations
#include <stdio.h>
#include <algorithm>
#include <string>
#include <vector>
#include "mutex.h"
#include "util.h"
#ifndef PATH_SEPARATOR
#define PATH_SEPARATOR '/'
#endif
// Special flags, type 1: the 'recursive' flags. They set another flag's val.
DEFINE_string(flagfile, "",
"load flags from file");
DEFINE_string(fromenv, "",
"set flags from the environment"
" [use 'export FLAGS_flag1=value']");
DEFINE_string(tryfromenv, "",
"set flags from the environment if present");
// Special flags, type 2: the 'parsing' flags. They modify how we parse.
DEFINE_string(undefok, "",
"comma-separated list of flag names that it is okay to specify "
"on the command line even if the program does not define a flag "
"with that name. IMPORTANT: flags in this list that have "
"arguments MUST use the flag=value format");
_START_GOOGLE_NAMESPACE_
using std::map;
using std::pair;
using std::sort;
using std::string;
using std::vector;
// This is used by the unittest to test error-exit code
void GFLAGS_DLL_DECL (*gflags_exitfunc)(int) = &exit; // from stdlib.h
// The help message indicating that the commandline flag has been
// 'stripped'. It will not show up when doing "-help" and its
// variants. The flag is stripped if STRIP_FLAG_HELP is set to 1
// before including base/gflags.h
// This is used by this file, and also in gflags_reporting.cc
const char kStrippedFlagHelp[] = "\001\002\003\004 (unknown) \004\003\002\001";
namespace {
// There are also 'reporting' flags, in gflags_reporting.cc.
static const char kError[] = "ERROR: ";
// Indicates that undefined options are to be ignored.
// Enables deferred processing of flags in dynamically loaded libraries.
static bool allow_command_line_reparsing = false;
static bool logging_is_probably_set_up = false;
// This is a 'prototype' validate-function. 'Real' validate
// functions, take a flag-value as an argument: ValidateFn(bool) or
// ValidateFn(uint64). However, for easier storage, we strip off this
// argument and then restore it when actually calling the function on
// a flag value.
typedef bool (*ValidateFnProto)();
// Whether we should die when reporting an error.
enum DieWhenReporting { DIE, DO_NOT_DIE };
// Report Error and exit if requested.
static void ReportError(DieWhenReporting should_die, const char* format, ...) {
char error_message[255];
va_list ap;
va_start(ap, format);
vsnprintf(error_message, sizeof(error_message), format, ap);
va_end(ap);
fprintf(stderr, "%s", error_message);
fflush(stderr); // should be unnecessary, but cygwin's rxvt buffers stderr
if (should_die == DIE) gflags_exitfunc(1);
// --------------------------------------------------------------------
// FlagValue
// This represent the value a single flag might have. The major
// functionality is to convert from a string to an object of a
// given type, and back. Thread-compatible.
// --------------------------------------------------------------------
class CommandLineFlag;
Loading
Loading full blame...