Significantly speed up CMake configuration phase (#6914)

This speeds up the configuration phase and simplifies having
control of the compilation flags used.

Additional changes were required due to other libraries incorrectly
depending on glog and gflags cmake code or headers.
smartmontools especially, was incorrectly publicly depending
on its own config.h, which was though taken from glog
when smartmontools libsmartclt.h header was included by user code.
A fix has been done on the smartmontools side and so the submodule
commit we refer to has been updated.
This commit is contained in:
Stefano Bonicatti 2021-01-27 03:26:59 +01:00 committed by GitHub
parent 22fde0abe6
commit 6893a72eef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
32 changed files with 10101 additions and 50 deletions

View File

@ -6,23 +6,70 @@
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only) # SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
function(gflagsMain) function(gflagsMain)
set(BUILD_gflags_nothreads_LIB false CACHE BOOL "" FORCE)
set(BUILD_gflags_LIB true CACHE BOOL "" FORCE)
set(library_root "${CMAKE_CURRENT_SOURCE_DIR}/src") set(library_root "${CMAKE_CURRENT_SOURCE_DIR}/src")
add_subdirectory("${library_root}" "${CMAKE_CURRENT_BINARY_DIR}/submodule" EXCLUDE_FROM_ALL)
copyInterfaceTargetFlagsTo(gflags_static thirdparty_cxx_settings PRIVATE) set(sources
"${library_root}/src/gflags.cc"
add_library(thirdparty_gflags INTERFACE) "${library_root}/src/gflags_reporting.cc"
target_link_libraries(thirdparty_gflags INTERFACE "${library_root}/src/gflags_completions.cc"
gflags_static
) )
target_include_directories(thirdparty_gflags SYSTEM INTERFACE add_library(thirdparty_gflags ${sources})
"${CMAKE_CURRENT_BINARY_DIR}/submodule/include"
if(DEFINED PLATFORM_LINUX)
target_include_directories(thirdparty_gflags
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/linux/private"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/linux/public"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/linux/public"
)
elseif(DEFINED PLATFORM_WINDOWS)
list(APPEND sources
"${library_root}/src/windows_port.cc"
)
target_include_directories(thirdparty_gflags
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/windows/private"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/windows/public"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/windows/public"
)
elseif(DEFINED PLATFORM_MACOS)
target_include_directories(thirdparty_gflags
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/macos/private"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/macos/public"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/macos/public"
)
endif()
target_compile_definitions(thirdparty_gflags
PUBLIC
GFLAGS_IS_A_DLL=0
GFLAGS_DLL_DECLARE_FLAG=
GFLAGS_DLL_DEFINE_FLAG=
) )
target_include_directories(thirdparty_gflags
PRIVATE
"${library_root}/src"
"${CMAKE_CURRENT_SOURCE_DIR}/generated"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated"
)
target_link_libraries(thirdparty_gflags PRIVATE
thirdparty_cxx_settings
)
endfunction() endfunction()
gflagsMain() gflagsMain()

View File

@ -0,0 +1,68 @@
# gflags
Notes to reproduce the library configuration and generated files
## Linux
Using CentOS 6.10 (glibc 2.12)
```sh
ldd --version
ldd (GNU libc) 2.12
```
Install CMake
```sh
wget https://cmake.org/files/v3.17/cmake-3.17.5-Linux-x86_64.tar.gz
sudo tar xvf cmake-3.17.5-Linux-x86_64.tar.gz -C /usr/local --strip 1
```
Install the osquery toolchain
```sh
wget https://github.com/osquery/osquery-toolchain/releases/download/1.1.0/osquery-toolchain-1.1.0-x86_64.tar.xz
sudo tar xvf osquery-toolchain-1.1.0-x86_64.tar.xz -C /usr/local
```
Configure with
```sh
cmake ../ -DCMAKE_BUILD_TYPE=Release -DBUILD_gflags_LIB=ON -DBUILD_gflags_nothreads_LIB=OFF -DGFLAGS_NAMESPACE=gflags -DCMAKE_SYSROOT=/usr/local/osquery-toolchain -DCMAKE_CXX_COMPILER=/usr/local/osquery-toolchain/usr/bin/clang++
```
## Windows
Configure with
```sh
cmake -G "Visual Studio 16 2019" -A x64 ../ -DBUILD_gflags_LIB=ON -DBUILD_gflags_nothreads_LIB=OFF -DGFLAGS_NAMESPACE=gflags
```
## macOS
Configure with
```sh
cmake ../ -DCMAKE_BUILD_TYPE=Release -DBUILD_gflags_LIB=ON -DBUILD_gflags_nothreads_LIB=OFF -DGFLAGS_NAMESPACE=gflags
```
## All platforms
Copy the generated files under `include` from the build folder, to the respective folders in the osquery source under `libraries/cmake/source/gflags/generated`
Copy only once (it's the same for all platforms)
```
include/gflags/gflags_completions.h -> generated/gflags/gflags_completions.h
```
Then copy for each os
```
include/gflags/defines.h -> generated/<os>/private/defines.h
include/gflags/gflags_declare.h -> generated/<os>/public/gflags/gflags_declare.h
include/gflags/gflags.h -> generated/<os>/public/gflags/gflags.h
```

View File

@ -0,0 +1,121 @@
// Copyright (c) 2008, 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.
//
// ---
//
// Implement helpful bash-style command line flag completions
//
// ** Functional API:
// HandleCommandLineCompletions() should be called early during
// program startup, but after command line flag code has been
// initialized, such as the beginning of HandleCommandLineHelpFlags().
// It checks the value of the flag --tab_completion_word. If this
// flag is empty, nothing happens here. If it contains a string,
// however, then HandleCommandLineCompletions() will hijack the
// process, attempting to identify the intention behind this
// completion. Regardless of the outcome of this deduction, the
// process will be terminated, similar to --helpshort flag
// handling.
//
// ** Overview of Bash completions:
// Bash can be told to programatically determine completions for the
// current 'cursor word'. It does this by (in this case) invoking a
// command with some additional arguments identifying the command
// being executed, the word being completed, and the previous word
// (if any). Bash then expects a sequence of output lines to be
// printed to stdout. If these lines all contain a common prefix
// longer than the cursor word, bash will replace the cursor word
// with that common prefix, and display nothing. If there isn't such
// a common prefix, bash will display the lines in pages using 'more'.
//
// ** Strategy taken for command line completions:
// If we can deduce either the exact flag intended, or a common flag
// prefix, we'll output exactly that. Otherwise, if information
// must be displayed to the user, we'll take the opportunity to add
// some helpful information beyond just the flag name (specifically,
// we'll include the default flag value and as much of the flag's
// description as can fit on a single terminal line width, as specified
// by the flag --tab_completion_columns). Furthermore, we'll try to
// make bash order the output such that the most useful or relevent
// flags are the most likely to be shown at the top.
//
// ** Additional features:
// To assist in finding that one really useful flag, substring matching
// was implemented. Before pressing a <TAB> to get completion for the
// current word, you can append one or more '?' to the flag to do
// substring matching. Here's the semantics:
// --foo<TAB> Show me all flags with names prefixed by 'foo'
// --foo?<TAB> Show me all flags with 'foo' somewhere in the name
// --foo??<TAB> Same as prior case, but also search in module
// definition path for 'foo'
// --foo???<TAB> Same as prior case, but also search in flag
// descriptions for 'foo'
// Finally, we'll trim the output to a relatively small number of
// flags to keep bash quiet about the verbosity of output. If one
// really wanted to see all possible matches, appending a '+' to the
// search word will force the exhaustive list of matches to be printed.
//
// ** How to have bash accept completions from a binary:
// Bash requires that it be informed about each command that programmatic
// completion should be enabled for. Example addition to a .bashrc
// file would be (your path to gflags_completions.sh file may differ):
/*
$ complete -o bashdefault -o default -o nospace -C \
'/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...]
*/
// This would allow the following to work:
// $ /path/to/binary_name --vmodule<TAB>
// Or:
// $ ./bin/path/another_binary --gfs_u<TAB>
// (etc)
//
// Sadly, it appears that bash gives no easy way to force this behavior for
// all commands. That's where the "time" in the above example comes in.
// If you haven't specifically added a command to the list of completion
// supported commands, you can still get completions by prefixing the
// entire command with "env".
// $ env /some/brand/new/binary --vmod<TAB>
// Assuming that "binary" is a newly compiled binary, this should still
// produce the expected completion output.
#ifndef GFLAGS_COMPLETIONS_H_
#define GFLAGS_COMPLETIONS_H_
namespace gflags {
extern void HandleCommandLineCompletions(void);
}
#endif // GFLAGS_COMPLETIONS_H_

View File

@ -0,0 +1,48 @@
/* Generated from defines.h.in during build configuration using CMake. */
// Note: This header file is only used internally. It is not part of public interface!
// Any cmakedefine is defined using the -D flag instead when Bazel is used.
// For Bazel, this file is thus not used to avoid a private file in $(GENDIR).
#ifndef GFLAGS_DEFINES_H_
#define GFLAGS_DEFINES_H_
// Define if you build this library for a MS Windows OS.
/* #undef OS_WINDOWS */
// Define if you have the <stdint.h> header file.
#define HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#define HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
#define HAVE_INTTYPES_H
// Define if you have the <sys/stat.h> header file.
#define HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
#define HAVE_UNISTD_H
// Define if you have the <fnmatch.h> header file.
#define HAVE_FNMATCH_H
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
/* #undef HAVE_SHLWAPI_H */
// Define if you have the strtoll function.
#define HAVE_STRTOLL
// Define if you have the strtoq function.
/* #undef HAVE_STRTOQ */
// Define if you have the <pthread.h> header file.
#define HAVE_PTHREAD
// Define if your pthread library defines the type pthread_rwlock_t
#define HAVE_RWLOCK
#endif // GFLAGS_DEFINES_H_

View File

@ -0,0 +1,626 @@
// Copyright (c) 2006, 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 is the file that should be included by any file which declares
// or defines a command line flag or wants to parse command line flags
// or print a program usage message (which will include information about
// flags). Executive summary, in the form of an example foo.cc file:
//
// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
// #include "validators.h" // hypothetical file defining ValidateIsFile()
//
// DEFINE_int32(end, 1000, "The last record to read");
//
// DEFINE_string(filename, "my_file.txt", "The file to read");
// // Crash if the specified file does not exist.
// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
// &ValidateIsFile);
//
// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
//
// void MyFunc() {
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// }
//
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
//
// For more details, see
// doc/gflags.html
//
// --- A note about thread-safety:
//
// We describe many functions in this routine as being thread-hostile,
// thread-compatible, or thread-safe. Here are the meanings we use:
//
// thread-safe: it is safe for multiple threads to call this routine
// (or, when referring to a class, methods of this class)
// concurrently.
// thread-hostile: it is not safe for multiple threads to call this
// routine (or methods of this class) concurrently. In gflags,
// most thread-hostile routines are intended to be called early in,
// or even before, main() -- that is, before threads are spawned.
// thread-compatible: it is safe for multiple threads to read from
// this variable (when applied to variables), or to call const
// methods of this class (when applied to classes), as long as no
// other thread is writing to the variable or calling non-const
// methods of this class.
#ifndef GFLAGS_GFLAGS_H_
#define GFLAGS_GFLAGS_H_
#include <string>
#include <vector>
#include "gflags/gflags_declare.h" // IWYU pragma: export
// We always want to export variables defined in user code
#ifndef GFLAGS_DLL_DEFINE_FLAG
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
namespace GFLAGS_NAMESPACE {
// --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool,
// DEFINE_string, etc. at the bottom of this file. You may also find
// it useful to register a validator with the flag. This ensures that
// when the flag is parsed from the commandline, or is later set via
// SetCommandLineOption, we call the validation function. It is _not_
// called when you assign the value to the flag directly using the = operator.
//
// The validation function should return true if the flag value is valid, and
// false otherwise. If the function returns false for the new setting of the
// flag, the flag will retain its current value. If it returns false for the
// default value, ParseCommandLineFlags() will die.
//
// This function is safe to call at global construct time (as in the
// example below).
//
// Example use:
// static bool ValidatePort(const char* flagname, int32 value) {
// if (value > 0 && value < 32768) // value is ok
// return true;
// printf("Invalid value for --%s: %d\n", flagname, (int)value);
// return false;
// }
// DEFINE_int32(port, 0, "What port to listen on");
// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
// Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag).
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
// Convenience macro for the registration of a flag validator
#define DEFINE_validator(name, validator) \
static const bool name##_validator_registered = \
GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
// --------------------------------------------------------------------
// These methods are the best way to get access to info about the
// list of commandline flags. Note that these routines are pretty slow.
// GetAllFlags: mostly-complete info about the list, sorted by file.
// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
//
// In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once.
//
// No need to export this data only structure from DLL, avoiding VS warning 4251.
struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
};
// Using this inside of a validator is a recipe for a deadlock.
// TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in
// gflags_unittest.sh
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in gflags_reporting.cc.
extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks.
extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is
// only called before any threads start.
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// --------------------------------------------------------------------
// Normally you access commandline flags by just saying "if (FLAGS_foo)"
// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
// commonly, via the DEFINE_foo macro). But if you need a bit more
// control, we have programmatic ways to get/set the flags as well.
// These programmatic ways to access flags are thread-safe, but direct
// access is only thread-compatible.
// Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
// Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value:
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times).
SET_FLAGS_VALUE,
// update the flag's value, but *only if* it has not yet been updated
// with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
SET_FLAG_IF_DEFAULT,
// set the flag's default value to this. If the flag has not yet updated
// yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
// change the flag's current value to the new default value as well.
SET_FLAGS_DEFAULT
};
// Set a particular flag ("command line option"). Returns a string
// describing the new value that the option has been set to. The
// return value API is not well-specified, so basically just depend on
// it to be empty if the setting failed for some reason -- the name is
// not a valid flag name, or the value is not a valid value -- and
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
// --------------------------------------------------------------------
// Saves the states (value, default value, whether the user has set
// the flag, registered validators, etc) of all flags, and restores
// them when the FlagSaver is destroyed. This is very useful in
// tests, say, when you want to let your tests change the flags, but
// make sure that they get reverted to the original states when your
// test is complete.
//
// Example usage:
// void TestFoo() {
// FlagSaver s1;
// FLAG_foo = false;
// FLAG_bar = "some value";
//
// // test happens here. You can return at any time
// // without worrying about restoring the FLAG values.
// }
//
// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an
// unused variable.
//
// This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class GFLAGS_DLL_DECL FlagSaver {
public:
FlagSaver();
~FlagSaver();
private:
class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&);
};
// --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
extern GFLAGS_DLL_DECL
bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality.
// DEPRECATED.
extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
// --------------------------------------------------------------------
// Useful routines for initializing flags from the environment.
// In each case, if 'varname' does not exist in the environment
// return defval. If 'varname' does exist but is not valid
// (e.g., not a number for an int32 flag), abort with an error.
// Otherwise, return the value. NOTE: for booleans, for true use
// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval);
extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
// --------------------------------------------------------------------
// The next two functions parse gflags from main():
// Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n");
// usage += argv[0] + " <uselessarg1> <uselessarg2>";
// SetUsageMessage(usage);
// Do not include commandline flags in the usage: we do that for you!
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true.
// If a flag is defined more than once in the command line or flag
// file, the last definition is used. Returns the index (into argv)
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
// Calls to ParseCommandLineNonHelpFlags and then to
// HandleCommandLineHelpFlags can be used instead of a call to
// ParseCommandLineFlags during initialization, in order to allow for
// changing default values for some FLAGS (via
// e.g. SetCommandLineOptionWithMode calls) between the time of
// command line parsing and the time of dumping help information for
// the flags as a result of command line parsing. If a flag is
// defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.)
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-(
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a
// later parse. Thread-hostile; meant to be called before any threads
// are spawned.
extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value
// must be provided as part of the argument using "=", not as a
// separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded.
extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal
// operation, or for the google perftools heap-checker. It must only
// be called when the process is about to exit, and all threads that
// might access flags are quiescent. Referencing flags after this is
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// --------------------------------------------------------------------
// Now come the command line flag declaration/definition macros that
// will actually be used. They're kind of hairy. A major reason
// for this is initialization: we want people to be able to access
// variables in global constructors and have that not crash, even if
// their global constructor runs before the global constructor here.
// (Obviously, we can't guarantee the flags will have the correct
// default value in that case, but at least accessing them is safe.)
// The only way to do that is have flags point to a static buffer.
// So we make one, using a union to ensure proper alignment, and
// then use placement-new to actually set up the flag with the
// correct default value. In the same vein, we have to worry about
// flag access in global destructors, so FlagRegisterer has to be
// careful never to destroy the flag-values it constructs.
//
// Note that when we define a flag variable FLAGS_<name>, we also
// preemptively define a junk variable, FLAGS_no<name>. This is to
// cause a link-time error if someone tries to define 2 flags with
// names like "logging" and "nologging". We do this because a bool
// flag FLAG can be set from the command line to true with a "-FLAG"
// argument, and to false with a "-noFLAG" argument, and so this can
// potentially avert confusion.
//
// We also put flags into their own namespace. It is purposefully
// named in an opaque way that people should have trouble typing
// directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere.
//
// We also put the type of the variable in the namespace, so that
// people can't DECLARE_int32 something that they DEFINE_bool'd
// elsewhere.
class GFLAGS_DLL_DECL FlagRegisterer {
public:
// We instantiate this template ctor for all supported types,
// so it is possible to place implementation of the FlagRegisterer ctor in
// .cc file.
// Calling this constructor with unsupported type will produce linker error.
template <typename FlagType>
FlagRegisterer(const char* name,
const char* help, const char* filename,
FlagType* current_storage, FlagType* defvalue_storage);
};
// Force compiler to not generate code for the given template specialization.
#if defined(_MSC_VER) && _MSC_VER < 1800 // Visual Studio 2013 version 12.0
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type)
#else
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type) \
extern template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \
const char* name, const char* help, const char* filename, \
type* current_storage, type* defvalue_storage)
#endif
// Do this for all supported flag types.
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(bool);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int32);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint32);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int64);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint64);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(double);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(std::string);
#undef GFLAGS_DECLARE_FLAG_REGISTERER_CTOR
// If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
#ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else
#define MAYBE_STRIPPED_HELP(txt) txt
#endif
// Each command-line flag has two variables associated with it: one
// with the current value, and one with the default value. However,
// we have a third variable, which is where value is assigned; it's a
// constant. This guarantees that FLAG_##value is initialized at
// static initialization time (e.g. before program-start) rather than
// than global construction time (which is after program-start but
// before main), at least when 'value' is a compile-time constant. We
// use a small trick for the "default value" variable, and call it
// FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
static type FLAGS_no##name = FLAGS_nono##name; \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in
// value is actually a bool, and not a string or something that can be
// coerced to a bool. These declarations (no definition needed!) will
// help us do that, and never evaluate From, which is important.
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a
// COMPILE_ASSERT.
namespace fLB {
struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB
// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
// are in a separate include, gflags_declare.h, for reducing
// the physical transitive size for DECLARE use.
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt)
#define DEFINE_int32(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DEFINE_uint32(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \
name, val, txt)
#define DEFINE_int64(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DEFINE_uint64(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DEFINE_double(name, val, txt) \
DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get
// constructed at global-constructor time, which is much later). To
// try to avoid crashes in that case, we use a char buffer to store
// the string, which we can static-initialize, and then placement-new
// into it later. It's not perfect, but the best we can do.
namespace fLS {
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) {
return new(stringspot) clstring(value);
}
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const clstring &value) {
return new(stringspot) clstring(value);
}
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value);
// Auxiliary class used to explicitly call destructor of string objects
// allocated using placement new during static program deinitialization.
// The destructor MUST be an inline function such that the explicit
// destruction occurs in the same compilation unit as the placement new.
class StringFlagDestructor {
void *current_storage_;
void *defvalue_storage_;
public:
StringFlagDestructor(void *current, void *defvalue)
: current_storage_(current), defvalue_storage_(defvalue) {}
~StringFlagDestructor() {
reinterpret_cast<clstring*>(current_storage_ )->~clstring();
reinterpret_cast<clstring*>(defvalue_storage_)->~clstring();
}
};
} // namespace fLS
// We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go
// great together!
// The weird 'using' + 'extern' inside the fLS namespace is to work around
// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
// http://code.google.com/p/google-gflags/issues/detail?id=20
#define DEFINE_string(name, val, txt) \
namespace fLS { \
using ::fLS::clstring; \
using ::fLS::StringFlagDestructor; \
static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, MAYBE_STRIPPED_HELP(txt), __FILE__, \
FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \
} \
using fLS::FLAGS_##name
#endif // SWIG
#endif // GFLAGS_GFLAGS_H_

View File

@ -0,0 +1,156 @@
// 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 is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE gflags
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// Whether gflags library is a DLL.
//
// Set to 1 by default when the shared gflags library was built on Windows.
// Must be overwritten when this header file is used with the optionally also
// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS.
#ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
// We always want to import the symbols of the gflags library.
#ifndef GFLAGS_DLL_DECL
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define GFLAGS_DLL_DECL __attribute__((visibility("default")))
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code.
#ifndef GFLAGS_DLL_DECLARE_FLAG
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define GFLAGS_DLL_DECLARE_FLAG __attribute__((visibility("default")))
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 1
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 1 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 0 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_uint32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -0,0 +1,48 @@
/* Generated from defines.h.in during build configuration using CMake. */
// Note: This header file is only used internally. It is not part of public interface!
// Any cmakedefine is defined using the -D flag instead when Bazel is used.
// For Bazel, this file is thus not used to avoid a private file in $(GENDIR).
#ifndef GFLAGS_DEFINES_H_
#define GFLAGS_DEFINES_H_
// Define if you build this library for a MS Windows OS.
/* #undef OS_WINDOWS */
// Define if you have the <stdint.h> header file.
#define HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#define HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
#define HAVE_INTTYPES_H
// Define if you have the <sys/stat.h> header file.
#define HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
#define HAVE_UNISTD_H
// Define if you have the <fnmatch.h> header file.
#define HAVE_FNMATCH_H
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
/* #undef HAVE_SHLWAPI_H */
// Define if you have the strtoll function.
#define HAVE_STRTOLL
// Define if you have the strtoq function.
/* #undef HAVE_STRTOQ */
// Define if you have the <pthread.h> header file.
#define HAVE_PTHREAD
// Define if your pthread library defines the type pthread_rwlock_t
#define HAVE_RWLOCK
#endif // GFLAGS_DEFINES_H_

View File

@ -0,0 +1,626 @@
// Copyright (c) 2006, 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 is the file that should be included by any file which declares
// or defines a command line flag or wants to parse command line flags
// or print a program usage message (which will include information about
// flags). Executive summary, in the form of an example foo.cc file:
//
// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
// #include "validators.h" // hypothetical file defining ValidateIsFile()
//
// DEFINE_int32(end, 1000, "The last record to read");
//
// DEFINE_string(filename, "my_file.txt", "The file to read");
// // Crash if the specified file does not exist.
// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
// &ValidateIsFile);
//
// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
//
// void MyFunc() {
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// }
//
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
//
// For more details, see
// doc/gflags.html
//
// --- A note about thread-safety:
//
// We describe many functions in this routine as being thread-hostile,
// thread-compatible, or thread-safe. Here are the meanings we use:
//
// thread-safe: it is safe for multiple threads to call this routine
// (or, when referring to a class, methods of this class)
// concurrently.
// thread-hostile: it is not safe for multiple threads to call this
// routine (or methods of this class) concurrently. In gflags,
// most thread-hostile routines are intended to be called early in,
// or even before, main() -- that is, before threads are spawned.
// thread-compatible: it is safe for multiple threads to read from
// this variable (when applied to variables), or to call const
// methods of this class (when applied to classes), as long as no
// other thread is writing to the variable or calling non-const
// methods of this class.
#ifndef GFLAGS_GFLAGS_H_
#define GFLAGS_GFLAGS_H_
#include <string>
#include <vector>
#include "gflags/gflags_declare.h" // IWYU pragma: export
// We always want to export variables defined in user code
#ifndef GFLAGS_DLL_DEFINE_FLAG
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
namespace GFLAGS_NAMESPACE {
// --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool,
// DEFINE_string, etc. at the bottom of this file. You may also find
// it useful to register a validator with the flag. This ensures that
// when the flag is parsed from the commandline, or is later set via
// SetCommandLineOption, we call the validation function. It is _not_
// called when you assign the value to the flag directly using the = operator.
//
// The validation function should return true if the flag value is valid, and
// false otherwise. If the function returns false for the new setting of the
// flag, the flag will retain its current value. If it returns false for the
// default value, ParseCommandLineFlags() will die.
//
// This function is safe to call at global construct time (as in the
// example below).
//
// Example use:
// static bool ValidatePort(const char* flagname, int32 value) {
// if (value > 0 && value < 32768) // value is ok
// return true;
// printf("Invalid value for --%s: %d\n", flagname, (int)value);
// return false;
// }
// DEFINE_int32(port, 0, "What port to listen on");
// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
// Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag).
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
// Convenience macro for the registration of a flag validator
#define DEFINE_validator(name, validator) \
static const bool name##_validator_registered = \
GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
// --------------------------------------------------------------------
// These methods are the best way to get access to info about the
// list of commandline flags. Note that these routines are pretty slow.
// GetAllFlags: mostly-complete info about the list, sorted by file.
// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
//
// In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once.
//
// No need to export this data only structure from DLL, avoiding VS warning 4251.
struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
};
// Using this inside of a validator is a recipe for a deadlock.
// TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in
// gflags_unittest.sh
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in gflags_reporting.cc.
extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks.
extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is
// only called before any threads start.
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// --------------------------------------------------------------------
// Normally you access commandline flags by just saying "if (FLAGS_foo)"
// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
// commonly, via the DEFINE_foo macro). But if you need a bit more
// control, we have programmatic ways to get/set the flags as well.
// These programmatic ways to access flags are thread-safe, but direct
// access is only thread-compatible.
// Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
// Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value:
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times).
SET_FLAGS_VALUE,
// update the flag's value, but *only if* it has not yet been updated
// with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
SET_FLAG_IF_DEFAULT,
// set the flag's default value to this. If the flag has not yet updated
// yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
// change the flag's current value to the new default value as well.
SET_FLAGS_DEFAULT
};
// Set a particular flag ("command line option"). Returns a string
// describing the new value that the option has been set to. The
// return value API is not well-specified, so basically just depend on
// it to be empty if the setting failed for some reason -- the name is
// not a valid flag name, or the value is not a valid value -- and
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
// --------------------------------------------------------------------
// Saves the states (value, default value, whether the user has set
// the flag, registered validators, etc) of all flags, and restores
// them when the FlagSaver is destroyed. This is very useful in
// tests, say, when you want to let your tests change the flags, but
// make sure that they get reverted to the original states when your
// test is complete.
//
// Example usage:
// void TestFoo() {
// FlagSaver s1;
// FLAG_foo = false;
// FLAG_bar = "some value";
//
// // test happens here. You can return at any time
// // without worrying about restoring the FLAG values.
// }
//
// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an
// unused variable.
//
// This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class GFLAGS_DLL_DECL FlagSaver {
public:
FlagSaver();
~FlagSaver();
private:
class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&);
};
// --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
extern GFLAGS_DLL_DECL
bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality.
// DEPRECATED.
extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
// --------------------------------------------------------------------
// Useful routines for initializing flags from the environment.
// In each case, if 'varname' does not exist in the environment
// return defval. If 'varname' does exist but is not valid
// (e.g., not a number for an int32 flag), abort with an error.
// Otherwise, return the value. NOTE: for booleans, for true use
// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval);
extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
// --------------------------------------------------------------------
// The next two functions parse gflags from main():
// Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n");
// usage += argv[0] + " <uselessarg1> <uselessarg2>";
// SetUsageMessage(usage);
// Do not include commandline flags in the usage: we do that for you!
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true.
// If a flag is defined more than once in the command line or flag
// file, the last definition is used. Returns the index (into argv)
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
// Calls to ParseCommandLineNonHelpFlags and then to
// HandleCommandLineHelpFlags can be used instead of a call to
// ParseCommandLineFlags during initialization, in order to allow for
// changing default values for some FLAGS (via
// e.g. SetCommandLineOptionWithMode calls) between the time of
// command line parsing and the time of dumping help information for
// the flags as a result of command line parsing. If a flag is
// defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.)
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-(
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a
// later parse. Thread-hostile; meant to be called before any threads
// are spawned.
extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value
// must be provided as part of the argument using "=", not as a
// separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded.
extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal
// operation, or for the google perftools heap-checker. It must only
// be called when the process is about to exit, and all threads that
// might access flags are quiescent. Referencing flags after this is
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// --------------------------------------------------------------------
// Now come the command line flag declaration/definition macros that
// will actually be used. They're kind of hairy. A major reason
// for this is initialization: we want people to be able to access
// variables in global constructors and have that not crash, even if
// their global constructor runs before the global constructor here.
// (Obviously, we can't guarantee the flags will have the correct
// default value in that case, but at least accessing them is safe.)
// The only way to do that is have flags point to a static buffer.
// So we make one, using a union to ensure proper alignment, and
// then use placement-new to actually set up the flag with the
// correct default value. In the same vein, we have to worry about
// flag access in global destructors, so FlagRegisterer has to be
// careful never to destroy the flag-values it constructs.
//
// Note that when we define a flag variable FLAGS_<name>, we also
// preemptively define a junk variable, FLAGS_no<name>. This is to
// cause a link-time error if someone tries to define 2 flags with
// names like "logging" and "nologging". We do this because a bool
// flag FLAG can be set from the command line to true with a "-FLAG"
// argument, and to false with a "-noFLAG" argument, and so this can
// potentially avert confusion.
//
// We also put flags into their own namespace. It is purposefully
// named in an opaque way that people should have trouble typing
// directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere.
//
// We also put the type of the variable in the namespace, so that
// people can't DECLARE_int32 something that they DEFINE_bool'd
// elsewhere.
class GFLAGS_DLL_DECL FlagRegisterer {
public:
// We instantiate this template ctor for all supported types,
// so it is possible to place implementation of the FlagRegisterer ctor in
// .cc file.
// Calling this constructor with unsupported type will produce linker error.
template <typename FlagType>
FlagRegisterer(const char* name,
const char* help, const char* filename,
FlagType* current_storage, FlagType* defvalue_storage);
};
// Force compiler to not generate code for the given template specialization.
#if defined(_MSC_VER) && _MSC_VER < 1800 // Visual Studio 2013 version 12.0
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type)
#else
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type) \
extern template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \
const char* name, const char* help, const char* filename, \
type* current_storage, type* defvalue_storage)
#endif
// Do this for all supported flag types.
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(bool);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int32);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint32);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int64);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint64);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(double);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(std::string);
#undef GFLAGS_DECLARE_FLAG_REGISTERER_CTOR
// If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
#ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else
#define MAYBE_STRIPPED_HELP(txt) txt
#endif
// Each command-line flag has two variables associated with it: one
// with the current value, and one with the default value. However,
// we have a third variable, which is where value is assigned; it's a
// constant. This guarantees that FLAG_##value is initialized at
// static initialization time (e.g. before program-start) rather than
// than global construction time (which is after program-start but
// before main), at least when 'value' is a compile-time constant. We
// use a small trick for the "default value" variable, and call it
// FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
static type FLAGS_no##name = FLAGS_nono##name; \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in
// value is actually a bool, and not a string or something that can be
// coerced to a bool. These declarations (no definition needed!) will
// help us do that, and never evaluate From, which is important.
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a
// COMPILE_ASSERT.
namespace fLB {
struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB
// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
// are in a separate include, gflags_declare.h, for reducing
// the physical transitive size for DECLARE use.
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt)
#define DEFINE_int32(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DEFINE_uint32(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \
name, val, txt)
#define DEFINE_int64(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DEFINE_uint64(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DEFINE_double(name, val, txt) \
DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get
// constructed at global-constructor time, which is much later). To
// try to avoid crashes in that case, we use a char buffer to store
// the string, which we can static-initialize, and then placement-new
// into it later. It's not perfect, but the best we can do.
namespace fLS {
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) {
return new(stringspot) clstring(value);
}
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const clstring &value) {
return new(stringspot) clstring(value);
}
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value);
// Auxiliary class used to explicitly call destructor of string objects
// allocated using placement new during static program deinitialization.
// The destructor MUST be an inline function such that the explicit
// destruction occurs in the same compilation unit as the placement new.
class StringFlagDestructor {
void *current_storage_;
void *defvalue_storage_;
public:
StringFlagDestructor(void *current, void *defvalue)
: current_storage_(current), defvalue_storage_(defvalue) {}
~StringFlagDestructor() {
reinterpret_cast<clstring*>(current_storage_ )->~clstring();
reinterpret_cast<clstring*>(defvalue_storage_)->~clstring();
}
};
} // namespace fLS
// We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go
// great together!
// The weird 'using' + 'extern' inside the fLS namespace is to work around
// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
// http://code.google.com/p/google-gflags/issues/detail?id=20
#define DEFINE_string(name, val, txt) \
namespace fLS { \
using ::fLS::clstring; \
using ::fLS::StringFlagDestructor; \
static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, MAYBE_STRIPPED_HELP(txt), __FILE__, \
FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \
} \
using fLS::FLAGS_##name
#endif // SWIG
#endif // GFLAGS_GFLAGS_H_

View File

@ -0,0 +1,156 @@
// 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 is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE gflags
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// Whether gflags library is a DLL.
//
// Set to 1 by default when the shared gflags library was built on Windows.
// Must be overwritten when this header file is used with the optionally also
// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS.
#ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
// We always want to import the symbols of the gflags library.
#ifndef GFLAGS_DLL_DECL
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define GFLAGS_DLL_DECL __attribute__((visibility("default")))
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code.
#ifndef GFLAGS_DLL_DECLARE_FLAG
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define GFLAGS_DLL_DECLARE_FLAG __attribute__((visibility("default")))
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 1
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 1 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 0 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_uint32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -0,0 +1,48 @@
/* Generated from defines.h.in during build configuration using CMake. */
// Note: This header file is only used internally. It is not part of public interface!
// Any cmakedefine is defined using the -D flag instead when Bazel is used.
// For Bazel, this file is thus not used to avoid a private file in $(GENDIR).
#ifndef GFLAGS_DEFINES_H_
#define GFLAGS_DEFINES_H_
// Define if you build this library for a MS Windows OS.
#define OS_WINDOWS
// Define if you have the <stdint.h> header file.
#define HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#define HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
#define HAVE_INTTYPES_H
// Define if you have the <sys/stat.h> header file.
#define HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
/* #undef HAVE_UNISTD_H */
// Define if you have the <fnmatch.h> header file.
/* #undef HAVE_FNMATCH_H */
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
#define HAVE_SHLWAPI_H
// Define if you have the strtoll function.
/* #undef HAVE_STRTOLL */
// Define if you have the strtoq function.
/* #undef HAVE_STRTOQ */
// Define if you have the <pthread.h> header file.
/* #undef HAVE_PTHREAD */
// Define if your pthread library defines the type pthread_rwlock_t
/* #undef HAVE_RWLOCK */
#endif // GFLAGS_DEFINES_H_

View File

@ -0,0 +1,626 @@
// Copyright (c) 2006, 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 is the file that should be included by any file which declares
// or defines a command line flag or wants to parse command line flags
// or print a program usage message (which will include information about
// flags). Executive summary, in the form of an example foo.cc file:
//
// #include "foo.h" // foo.h has a line "DECLARE_int32(start);"
// #include "validators.h" // hypothetical file defining ValidateIsFile()
//
// DEFINE_int32(end, 1000, "The last record to read");
//
// DEFINE_string(filename, "my_file.txt", "The file to read");
// // Crash if the specified file does not exist.
// static bool dummy = RegisterFlagValidator(&FLAGS_filename,
// &ValidateIsFile);
//
// DECLARE_bool(verbose); // some other file has a DEFINE_bool(verbose, ...)
//
// void MyFunc() {
// if (FLAGS_verbose) printf("Records %d-%d\n", FLAGS_start, FLAGS_end);
// }
//
// Then, at the command-line:
// ./foo --noverbose --start=5 --end=100
//
// For more details, see
// doc/gflags.html
//
// --- A note about thread-safety:
//
// We describe many functions in this routine as being thread-hostile,
// thread-compatible, or thread-safe. Here are the meanings we use:
//
// thread-safe: it is safe for multiple threads to call this routine
// (or, when referring to a class, methods of this class)
// concurrently.
// thread-hostile: it is not safe for multiple threads to call this
// routine (or methods of this class) concurrently. In gflags,
// most thread-hostile routines are intended to be called early in,
// or even before, main() -- that is, before threads are spawned.
// thread-compatible: it is safe for multiple threads to read from
// this variable (when applied to variables), or to call const
// methods of this class (when applied to classes), as long as no
// other thread is writing to the variable or calling non-const
// methods of this class.
#ifndef GFLAGS_GFLAGS_H_
#define GFLAGS_GFLAGS_H_
#include <string>
#include <vector>
#include "gflags/gflags_declare.h" // IWYU pragma: export
// We always want to export variables defined in user code
#ifndef GFLAGS_DLL_DEFINE_FLAG
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
namespace GFLAGS_NAMESPACE {
// --------------------------------------------------------------------
// To actually define a flag in a file, use DEFINE_bool,
// DEFINE_string, etc. at the bottom of this file. You may also find
// it useful to register a validator with the flag. This ensures that
// when the flag is parsed from the commandline, or is later set via
// SetCommandLineOption, we call the validation function. It is _not_
// called when you assign the value to the flag directly using the = operator.
//
// The validation function should return true if the flag value is valid, and
// false otherwise. If the function returns false for the new setting of the
// flag, the flag will retain its current value. If it returns false for the
// default value, ParseCommandLineFlags() will die.
//
// This function is safe to call at global construct time (as in the
// example below).
//
// Example use:
// static bool ValidatePort(const char* flagname, int32 value) {
// if (value > 0 && value < 32768) // value is ok
// return true;
// printf("Invalid value for --%s: %d\n", flagname, (int)value);
// return false;
// }
// DEFINE_int32(port, 0, "What port to listen on");
// static bool dummy = RegisterFlagValidator(&FLAGS_port, &ValidatePort);
// Returns true if successfully registered, false if not (because the
// first argument doesn't point to a command-line flag, or because a
// validator is already registered for this flag).
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool* flag, bool (*validate_fn)(const char*, bool));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32* flag, bool (*validate_fn)(const char*, int32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint32* flag, bool (*validate_fn)(const char*, uint32));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64* flag, bool (*validate_fn)(const char*, int64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64* flag, bool (*validate_fn)(const char*, uint64));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double* flag, bool (*validate_fn)(const char*, double));
extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
// Convenience macro for the registration of a flag validator
#define DEFINE_validator(name, validator) \
static const bool name##_validator_registered = \
GFLAGS_NAMESPACE::RegisterFlagValidator(&FLAGS_##name, validator)
// --------------------------------------------------------------------
// These methods are the best way to get access to info about the
// list of commandline flags. Note that these routines are pretty slow.
// GetAllFlags: mostly-complete info about the list, sorted by file.
// ShowUsageWithFlags: pretty-prints the list to stdout (what --help does)
// ShowUsageWithFlagsRestrict: limit to filenames with restrict as a substr
//
// In addition to accessing flags, you can also access argv[0] (the program
// name) and argv (the entire commandline), which we sock away a copy of.
// These variables are static, so you should only set them once.
//
// No need to export this data only structure from DLL, avoiding VS warning 4251.
struct CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
std::string description; // the "help text" associated with the flag
std::string current_value; // the current value, as a string
std::string default_value; // the default value, as a string
std::string filename; // 'cleaned' version of filename holding the flag
bool has_validator_fn; // true if RegisterFlagValidator called on this flag
bool is_default; // true if the flag has the default value and
// has not been set explicitly from the cmdline
// or via SetCommandLineOption
const void* flag_ptr; // pointer to the flag's current value (i.e. FLAGS_foo)
};
// Using this inside of a validator is a recipe for a deadlock.
// TODO(user) Fix locking when validators are running, to make it safe to
// call validators during ParseAllFlags.
// Also make sure then to uncomment the corresponding unit test in
// gflags_unittest.sh
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in gflags_reporting.cc.
extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0); // what --help does
extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
// Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks.
extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
// The following functions are thread-safe as long as SetArgv() is
// only called before any threads start.
extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
extern GFLAGS_DLL_DECL const char* GetArgv(); // all of argv as a string
extern GFLAGS_DLL_DECL const char* GetArgv0(); // only argv0
extern GFLAGS_DLL_DECL uint32 GetArgvSum(); // simple checksum of argv
extern GFLAGS_DLL_DECL const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName(); // basename(argv0)
// ProgramUsage() is thread-safe as long as SetUsageMessage() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* ProgramUsage(); // string set by SetUsageMessage()
// VersionString() is thread-safe as long as SetVersionString() is only
// called before any threads start.
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
// --------------------------------------------------------------------
// Normally you access commandline flags by just saying "if (FLAGS_foo)"
// or whatever, and set them by calling "FLAGS_foo = bar" (or, more
// commonly, via the DEFINE_foo macro). But if you need a bit more
// control, we have programmatic ways to get/set the flags as well.
// These programmatic ways to access flags are thread-safe, but direct
// access is only thread-compatible.
// Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
// Return true iff the flagname was found. OUTPUT is set to the flag's
// CommandLineFlagInfo or unchanged if we return false.
extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
// Return the CommandLineFlagInfo of the flagname. exit() if name not found.
// Example usage, to check if a flag's value is currently the default value:
// if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times).
SET_FLAGS_VALUE,
// update the flag's value, but *only if* it has not yet been updated
// with SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef".
SET_FLAG_IF_DEFAULT,
// set the flag's default value to this. If the flag has not yet updated
// yet (via SET_FLAGS_VALUE, SET_FLAG_IF_DEFAULT, or "FLAGS_xxx = nondef")
// change the flag's current value to the new default value as well.
SET_FLAGS_DEFAULT
};
// Set a particular flag ("command line option"). Returns a string
// describing the new value that the option has been set to. The
// return value API is not well-specified, so basically just depend on
// it to be empty if the setting failed for some reason -- the name is
// not a valid flag name, or the value is not a valid value -- and
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern GFLAGS_DLL_DECL std::string SetCommandLineOption (const char* name, const char* value);
extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
// --------------------------------------------------------------------
// Saves the states (value, default value, whether the user has set
// the flag, registered validators, etc) of all flags, and restores
// them when the FlagSaver is destroyed. This is very useful in
// tests, say, when you want to let your tests change the flags, but
// make sure that they get reverted to the original states when your
// test is complete.
//
// Example usage:
// void TestFoo() {
// FlagSaver s1;
// FLAG_foo = false;
// FLAG_bar = "some value";
//
// // test happens here. You can return at any time
// // without worrying about restoring the FLAG values.
// }
//
// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
// the work is done in the constructor and destructor, so in the standard
// usage example above, the compiler would complain that it's an
// unused variable.
//
// This class is thread-safe. However, its destructor writes to
// exactly the set of flags that have changed value during its
// lifetime, so concurrent _direct_ access to those flags
// (i.e. FLAGS_foo instead of {Get,Set}CommandLineOption()) is unsafe.
class GFLAGS_DLL_DECL FlagSaver {
public:
FlagSaver();
~FlagSaver();
private:
class FlagSaverImpl* impl_; // we use pimpl here to keep API steady
FlagSaver(const FlagSaver&); // no copying!
void operator=(const FlagSaver&);
};
// --------------------------------------------------------------------
// Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
extern GFLAGS_DLL_DECL
bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
// These let you manually implement --flagfile functionality.
// DEPRECATED.
extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal); // uses SET_FLAGS_VALUE
// --------------------------------------------------------------------
// Useful routines for initializing flags from the environment.
// In each case, if 'varname' does not exist in the environment
// return defval. If 'varname' does exist but is not valid
// (e.g., not a number for an int32 flag), abort with an error.
// Otherwise, return the value. NOTE: for booleans, for true use
// 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
extern GFLAGS_DLL_DECL uint32 Uint32FromEnv(const char *varname, uint32 defval);
extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
// --------------------------------------------------------------------
// The next two functions parse gflags from main():
// Set the "usage" message for this program. For example:
// string usage("This program does nothing. Sample usage:\n");
// usage += argv[0] + " <uselessarg1> <uselessarg2>";
// SetUsageMessage(usage);
// Do not include commandline flags in the usage: we do that for you!
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
// Sets the version string, which is emitted with --version.
// For instance: SetVersionString("1.3");
// Thread-hostile; meant to be called before any threads are spawned.
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
// flags first, or removes them entirely if remove_flags is true.
// If a flag is defined more than once in the command line or flag
// file, the last definition is used. Returns the index (into argv)
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
// Calls to ParseCommandLineNonHelpFlags and then to
// HandleCommandLineHelpFlags can be used instead of a call to
// ParseCommandLineFlags during initialization, in order to allow for
// changing default values for some FLAGS (via
// e.g. SetCommandLineOptionWithMode calls) between the time of
// command line parsing and the time of dumping help information for
// the flags as a result of command line parsing. If a flag is
// defined more than once in the command line or flag file, the last
// definition is used. Returns the index (into argv) of the first
// non-flag argument. (If remove_flags is true, will always return 1.)
extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
// This is actually defined in gflags_reporting.cc.
// This function is misnamed (it also handles --version, etc.), but
// it's too late to change that now. :-(
extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
// Allow command line reparsing. Disables the error normally
// generated when an unknown flag is found, since it may be found in a
// later parse. Thread-hostile; meant to be called before any threads
// are spawned.
extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
// Reparse the flags that have not yet been recognized. Only flags
// registered since the last parse will be recognized. Any flag value
// must be provided as part of the argument using "=", not as a
// separate command line argument that follows the flag argument.
// Intended for handling flags from dynamically loaded libraries,
// since their flags are not registered until they are loaded.
extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
// Clean up memory allocated by flags. This is only needed to reduce
// the quantity of "potentially leaked" reports emitted by memory
// debugging tools such as valgrind. It is not required for normal
// operation, or for the google perftools heap-checker. It must only
// be called when the process is about to exit, and all threads that
// might access flags are quiescent. Referencing flags after this is
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// --------------------------------------------------------------------
// Now come the command line flag declaration/definition macros that
// will actually be used. They're kind of hairy. A major reason
// for this is initialization: we want people to be able to access
// variables in global constructors and have that not crash, even if
// their global constructor runs before the global constructor here.
// (Obviously, we can't guarantee the flags will have the correct
// default value in that case, but at least accessing them is safe.)
// The only way to do that is have flags point to a static buffer.
// So we make one, using a union to ensure proper alignment, and
// then use placement-new to actually set up the flag with the
// correct default value. In the same vein, we have to worry about
// flag access in global destructors, so FlagRegisterer has to be
// careful never to destroy the flag-values it constructs.
//
// Note that when we define a flag variable FLAGS_<name>, we also
// preemptively define a junk variable, FLAGS_no<name>. This is to
// cause a link-time error if someone tries to define 2 flags with
// names like "logging" and "nologging". We do this because a bool
// flag FLAG can be set from the command line to true with a "-FLAG"
// argument, and to false with a "-noFLAG" argument, and so this can
// potentially avert confusion.
//
// We also put flags into their own namespace. It is purposefully
// named in an opaque way that people should have trouble typing
// directly. The idea is that DEFINE puts the flag in the weird
// namespace, and DECLARE imports the flag from there into the current
// namespace. The net result is to force people to use DECLARE to get
// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
// or some such instead. We want this so we can put extra
// functionality (like sanity-checking) in DECLARE if we want, and
// make sure it is picked up everywhere.
//
// We also put the type of the variable in the namespace, so that
// people can't DECLARE_int32 something that they DEFINE_bool'd
// elsewhere.
class GFLAGS_DLL_DECL FlagRegisterer {
public:
// We instantiate this template ctor for all supported types,
// so it is possible to place implementation of the FlagRegisterer ctor in
// .cc file.
// Calling this constructor with unsupported type will produce linker error.
template <typename FlagType>
FlagRegisterer(const char* name,
const char* help, const char* filename,
FlagType* current_storage, FlagType* defvalue_storage);
};
// Force compiler to not generate code for the given template specialization.
#if defined(_MSC_VER) && _MSC_VER < 1800 // Visual Studio 2013 version 12.0
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type)
#else
#define GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(type) \
extern template GFLAGS_DLL_DECL FlagRegisterer::FlagRegisterer( \
const char* name, const char* help, const char* filename, \
type* current_storage, type* defvalue_storage)
#endif
// Do this for all supported flag types.
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(bool);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int32);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint32);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(int64);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(uint64);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(double);
GFLAGS_DECLARE_FLAG_REGISTERER_CTOR(std::string);
#undef GFLAGS_DECLARE_FLAG_REGISTERER_CTOR
// If your application #defines STRIP_FLAG_HELP to a non-zero value
// before #including this file, we remove the help message from the
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
#ifndef SWIG // In swig, ignore the main flag declarations
#if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
// Need this construct to avoid the 'defined but not used' warning.
#define MAYBE_STRIPPED_HELP(txt) \
(false ? (txt) : GFLAGS_NAMESPACE::kStrippedFlagHelp)
#else
#define MAYBE_STRIPPED_HELP(txt) txt
#endif
// Each command-line flag has two variables associated with it: one
// with the current value, and one with the default value. However,
// we have a third variable, which is where value is assigned; it's a
// constant. This guarantees that FLAG_##value is initialized at
// static initialization time (e.g. before program-start) rather than
// than global construction time (which is after program-start but
// before main), at least when 'value' is a compile-time constant. We
// use a small trick for the "default value" variable, and call it
// FLAGS_no<name>. This serves the second purpose of assuring a
// compile error if someone tries to define a flag named no<name>
// which is illegal (--foo and --nofoo both affect the "foo" flag).
#define DEFINE_VARIABLE(type, shorttype, name, value, help) \
namespace fL##shorttype { \
static const type FLAGS_nono##name = value; \
/* We always want to export defined variables, dll or no */ \
GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name; \
static type FLAGS_no##name = FLAGS_nono##name; \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, MAYBE_STRIPPED_HELP(help), __FILE__, \
&FLAGS_##name, &FLAGS_no##name); \
} \
using fL##shorttype::FLAGS_##name
// For DEFINE_bool, we want to do the extra check that the passed-in
// value is actually a bool, and not a string or something that can be
// coerced to a bool. These declarations (no definition needed!) will
// help us do that, and never evaluate From, which is important.
// We'll use 'sizeof(IsBool(val))' to distinguish. This code requires
// that the compiler have different sizes for bool & double. Since
// this is not guaranteed by the standard, we check it with a
// COMPILE_ASSERT.
namespace fLB {
struct CompileAssert {};
typedef CompileAssert expected_sizeof_double_neq_sizeof_bool[
(sizeof(double) != sizeof(bool)) ? 1 : -1];
template<typename From> double GFLAGS_DLL_DECL IsBoolFlag(const From& from);
GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
} // namespace fLB
// Here are the actual DEFINE_*-macros. The respective DECLARE_*-macros
// are in a separate include, gflags_declare.h, for reducing
// the physical transitive size for DECLARE use.
#define DEFINE_bool(name, val, txt) \
namespace fLB { \
typedef ::fLB::CompileAssert FLAG_##name##_value_is_not_a_bool[ \
(sizeof(::fLB::IsBoolFlag(val)) != sizeof(double))? 1: -1]; \
} \
DEFINE_VARIABLE(bool, B, name, val, txt)
#define DEFINE_int32(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int32, I, \
name, val, txt)
#define DEFINE_uint32(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint32, U, \
name, val, txt)
#define DEFINE_int64(name, val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::int64, I64, \
name, val, txt)
#define DEFINE_uint64(name,val, txt) \
DEFINE_VARIABLE(GFLAGS_NAMESPACE::uint64, U64, \
name, val, txt)
#define DEFINE_double(name, val, txt) \
DEFINE_VARIABLE(double, D, name, val, txt)
// Strings are trickier, because they're not a POD, so we can't
// construct them at static-initialization time (instead they get
// constructed at global-constructor time, which is much later). To
// try to avoid crashes in that case, we use a char buffer to store
// the string, which we can static-initialize, and then placement-new
// into it later. It's not perfect, but the best we can do.
namespace fLS {
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const char *value) {
return new(stringspot) clstring(value);
}
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
const clstring &value) {
return new(stringspot) clstring(value);
}
inline clstring* dont_pass0toDEFINE_string(char *stringspot,
int value);
// Auxiliary class used to explicitly call destructor of string objects
// allocated using placement new during static program deinitialization.
// The destructor MUST be an inline function such that the explicit
// destruction occurs in the same compilation unit as the placement new.
class StringFlagDestructor {
void *current_storage_;
void *defvalue_storage_;
public:
StringFlagDestructor(void *current, void *defvalue)
: current_storage_(current), defvalue_storage_(defvalue) {}
~StringFlagDestructor() {
reinterpret_cast<clstring*>(current_storage_ )->~clstring();
reinterpret_cast<clstring*>(defvalue_storage_)->~clstring();
}
};
} // namespace fLS
// We need to define a var named FLAGS_no##name so people don't define
// --string and --nostring. And we need a temporary place to put val
// so we don't have to evaluate it twice. Two great needs that go
// great together!
// The weird 'using' + 'extern' inside the fLS namespace is to work around
// an unknown compiler bug/issue with the gcc 4.2.1 on SUSE 10. See
// http://code.google.com/p/google-gflags/issues/detail?id=20
#define DEFINE_string(name, val, txt) \
namespace fLS { \
using ::fLS::clstring; \
using ::fLS::StringFlagDestructor; \
static union { void* align; char s[sizeof(clstring)]; } s_##name[2]; \
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, MAYBE_STRIPPED_HELP(txt), __FILE__, \
FLAGS_no##name, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
static StringFlagDestructor d_##name(s_##name[0].s, s_##name[1].s); \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
using fLS::FLAGS_##name; \
clstring& FLAGS_##name = *FLAGS_no##name; \
} \
using fLS::FLAGS_##name
#endif // SWIG
#endif // GFLAGS_GFLAGS_H_

View File

@ -0,0 +1,156 @@
// 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 is the file that should be included by any file which declares
// command line flag.
#ifndef GFLAGS_DECLARE_H_
#define GFLAGS_DECLARE_H_
// ---------------------------------------------------------------------------
// Namespace of gflags library symbols.
#define GFLAGS_NAMESPACE gflags
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// Whether gflags library is a DLL.
//
// Set to 1 by default when the shared gflags library was built on Windows.
// Must be overwritten when this header file is used with the optionally also
// built static library instead; set by CMake's INTERFACE_COMPILE_DEFINITIONS.
#ifndef GFLAGS_IS_A_DLL
# define GFLAGS_IS_A_DLL 0
#endif
// We always want to import the symbols of the gflags library.
#ifndef GFLAGS_DLL_DECL
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define GFLAGS_DLL_DECL __attribute__((visibility("default")))
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// We always want to import variables declared in user code.
#ifndef GFLAGS_DLL_DECLARE_FLAG
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# elif defined(__GNUC__) && __GNUC__ >= 4
# define GFLAGS_DLL_DECLARE_FLAG __attribute__((visibility("default")))
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if 1
# include <stdint.h> // the normal place uint32_t is defined
#elif 1
# include <sys/types.h> // the normal place u_int32_t is defined
#elif 1
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
namespace GFLAGS_NAMESPACE {
#if 0 // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif 0 // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 1 // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
# error Do not know how to define a 32-bit integer quantity on your system
#endif
} // namespace GFLAGS_NAMESPACE
namespace fLS {
// The meaning of "string" might be different between now and when the
// macros below get invoked (e.g., if someone is experimenting with
// other string implementations that get defined after this file is
// included). Save the current meaning now and use it in the macros.
typedef std::string clstring;
} // namespace fLS
#define DECLARE_VARIABLE(type, shorttype, name) \
/* We always want to import declared variables, dll or no */ \
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int32, I, name)
#define DECLARE_uint32(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint32, U, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::GFLAGS_NAMESPACE::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \
/* We always want to import declared variables, dll or no */ \
namespace fLS { \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
#endif // GFLAGS_DECLARE_H_

View File

@ -6,40 +6,91 @@
# SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only) # SPDX-License-Identifier: (Apache-2.0 OR GPL-2.0-only)
function(googleLogMain) function(googleLogMain)
set(disabled_option_list
WITH_TLS
WITH_GFLAGS
)
set(enabled_option_list
HAVE_LIB_GFLAGS
WITH_THREADS
)
foreach(option_name ${disabled_option_list})
set("${option_name}" false CACHE BOOL "" FORCE)
endforeach()
foreach(option_name ${enabled_option_list})
set("${option_name}" true CACHE BOOL "" FORCE)
endforeach()
set(library_root "${CMAKE_CURRENT_SOURCE_DIR}/src") set(library_root "${CMAKE_CURRENT_SOURCE_DIR}/src")
add_subdirectory("${library_root}" "${CMAKE_CURRENT_BINARY_DIR}/submodule" EXCLUDE_FROM_ALL)
copyInterfaceTargetFlagsTo(glog thirdparty_cxx_settings PRIVATE) set(sources
"${library_root}/src/demangle.cc"
"${library_root}/src/logging.cc"
"${library_root}/src/raw_logging.cc"
"${library_root}/src/symbolize.cc"
"${library_root}/src/utilities.cc"
"${library_root}/src/vlog_is_on.cc"
"${library_root}/src/signalhandler.cc"
)
get_target_property(gflags_include_directory thirdparty_gflags INTERFACE_INCLUDE_DIRECTORIES) configure_file("${library_root}/src/glog/log_severity.h" "${CMAKE_CURRENT_BINARY_DIR}/glog/log_severity.h" COPYONLY)
target_include_directories(glog PRIVATE "${gflags_include_directory}")
# Small hack to set glog's includes as SYSTEM if(DEFINED PLATFORM_WINDOWS)
get_target_property(glog_include_directory glog INTERFACE_INCLUDE_DIRECTORIES) list(APPEND sources
target_include_directories(glog SYSTEM INTERFACE ${glog_include_directory}) "${library_root}/src/windows/port.cc"
)
endif()
add_library(thirdparty_glog INTERFACE) add_library(thirdparty_glog ${sources})
target_link_libraries(thirdparty_glog INTERFACE
glog if(DEFINED PLATFORM_POSIX)
thirdparty_gflags target_compile_options(thirdparty_glog PUBLIC
-Wno-unnamed-type-template-args
)
elseif(DEFINED PLATFORM_WINDOWS)
target_compile_definitions(thirdparty_glog
PRIVATE
HAVE_SNPRINTF
PUBLIC
GLOG_NO_ABBREVIATED_SEVERITIES
)
endif()
target_compile_definitions(thirdparty_glog PUBLIC
GOOGLE_GLOG_DLL_DECL=
)
target_link_libraries(thirdparty_glog
PRIVATE
thirdparty_cxx_settings
PUBLIC
thirdparty_gflags
)
if(DEFINED PLATFORM_LINUX)
target_include_directories(thirdparty_glog
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/linux/private"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/linux/public"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/linux/public"
)
elseif(DEFINED PLATFORM_WINDOWS)
target_include_directories(thirdparty_glog
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/windows/private"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/windows/public"
"${library_root}/src/windows"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/windows/public"
"${library_root}/src/windows"
)
elseif(DEFINED PLATFORM_MACOS)
target_include_directories(thirdparty_glog
PRIVATE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/macos/private"
"${CMAKE_CURRENT_SOURCE_DIR}/generated/macos/public"
SYSTEM INTERFACE
"${CMAKE_CURRENT_SOURCE_DIR}/generated/macos/public"
)
endif()
target_include_directories(thirdparty_glog
PRIVATE
"${library_root}/src"
"${CMAKE_CURRENT_BINARY_DIR}"
SYSTEM INTERFACE
"${CMAKE_CURRENT_BINARY_DIR}"
) )
endfunction() endfunction()

View File

@ -0,0 +1,62 @@
# glog
Notes to reproduce the library configuration and generated files
## Linux
Using CentOS 6.10 (glibc 2.12)
```sh
ldd --version
ldd (GNU libc) 2.12
```
Install CMake
```sh
wget https://cmake.org/files/v3.17/cmake-3.17.5-Linux-x86_64.tar.gz
sudo tar xvf cmake-3.17.5-Linux-x86_64.tar.gz -C /usr/local --strip 1
```
Install the osquery toolchain
```sh
wget https://github.com/osquery/osquery-toolchain/releases/download/1.1.0/osquery-toolchain-1.1.0-x86_64.tar.xz
sudo tar xvf osquery-toolchain-1.1.0-x86_64.tar.xz -C /usr/local
```
Configure with
```sh
cmake ../ -DCMAKE_BUILD_TYPE=Release -DWITH_TLS=OFF -DWITH_GFLAGS=OFF -DWITH_THREADS=ON -DHAVE_LIB_GFLAGS=ON -DCMAKE_SYSROOT=/usr/local/osquery-toolchain -DCMAKE_CXX_COMPILER=/usr/local/osquery-toolchain/usr/bin/clang++ -DCMAKE_C_COMPILER=/usr/local/osquery-toolchain/usr/bin/clang -DCMAKE_C_FLAGS="-pthread" -DCMAKE_CXX_FLAGS="-pthread"
```
## Windows
Configure with
```sh
cmake -G "Visual Studio 16 2019" -A x64 ../ -DWITH_TLS=OFF -DWITH_GFLAGS=OFF -DWITH_THREADS=ON -DHAVE_LIB_GFLAGS=ON
```
## macOS
Configure with
```sh
cmake ../ -DCMAKE_BUILD_TYPE=Release -DWITH_TLS=OFF -DWITH_GFLAGS=OFF -DWITH_THREADS=ON -DHAVE_LIB_GFLAGS=ON
```
## All platforms
Copy the generated files from the build folder, to the respective folders in the osquery source under `libraries/cmake/source/glog/generated`
```
glog -> libraries/cmake/source/glog/generated/<os>/public/glog
config.h -> libraries/cmake/source/glog/generated/<os>/private/config.h
```
Edit `TEST_SRC_DIR` in `generated/<os>/private/config.h` and set it to `""`, since it's not necessary

View File

@ -0,0 +1,216 @@
#ifndef GLOG_CONFIG_H
#define GLOG_CONFIG_H
/* define if glog doesn't use RTTI */
/* #undef DISABLE_RTTI */
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE google
/* Define if you have the `dladdr' function */
/* #undef HAVE_DLADDR */
/* Define if you have the `snprintf' function */
#define HAVE_SNPRINTF
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H
/* Define to 1 if you have the <execinfo.h> header file. */
#define HAVE_EXECINFO_H
/* Define if you have the `fcntl' function */
#define HAVE_FCNTL
/* Define to 1 if you have the <glob.h> header file. */
#define HAVE_GLOB_H
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
/* #undef HAVE_LIBPTHREAD */
/* Define to 1 if you have the <libunwind.h> header file. */
/* #undef HAVE_LIBUNWIND_H */
/* define if you have google gflags library */
#define HAVE_LIB_GFLAGS
/* define if you have google gmock library */
/* #undef HAVE_LIB_GMOCK */
/* define if you have google gtest library */
/* #undef HAVE_LIB_GTEST */
/* define if you have libunwind */
/* #undef HAVE_LIB_UNWIND */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
/* define to disable multithreading support. */
/* #undef NO_THREADS */
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES
/* Define if you have the 'pread' function */
#define HAVE_PREAD
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H
/* Define if you have the 'pwrite' function */
#define HAVE_PWRITE
/* define if the compiler implements pthread_rwlock_* */
#define HAVE_RWLOCK
/* Define if you have the 'sigaction' function */
#define HAVE_SIGACTION
/* Define if you have the `sigaltstack' function */
/* #undef HAVE_SIGALTSTACK */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define to 1 if you have the <syscall.h> header file. */
#define HAVE_SYSCALL_H
/* Define to 1 if you have the <syslog.h> header file. */
#define HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/syscall.h> header file. */
#define HAVE_SYS_SYSCALL_H
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/ucontext.h> header file. */
/* #undef HAVE_SYS_UCONTEXT_H */
/* Define to 1 if you have the <sys/utsname.h> header file. */
#define HAVE_SYS_UTSNAME_H
/* Define to 1 if you have the <ucontext.h> header file. */
#define HAVE_UCONTEXT_H
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <unwind.h> header file. */
#define HAVE_UNWIND_H 1
/* define if the compiler supports using expression for operator */
#define HAVE_USING_OPERATOR
/* define if your compiler has __attribute__ */
#define HAVE___ATTRIBUTE__
/* define if your compiler has __builtin_expect */
#define HAVE___BUILTIN_EXPECT 1
/* define if your compiler has __sync_val_compare_and_swap */
#define HAVE___SYNC_VAL_COMPARE_AND_SWAP
/* define if symbolize support is available */
#define HAVE_SYMBOLIZE
/* define if localtime_r is available in time.h */
#define HAVE_LOCALTIME_R
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* #undef LT_OBJDIR */
/* Name of package */
/* #undef PACKAGE */
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the home page for this package. */
/* #undef PACKAGE_URL */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* How to access the PC from a struct ucontext */
/* #undef PC_FROM_UCONTEXT */
/* define if we should print raw pc values on symbolization failure. */
/* #undef PRINT_UNSYMBOLIZED_STACK_TRACES */
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 8
/* Define to 1 if you have the ANSI C header files. */
/* #undef STDC_HEADERS */
/* the namespace where STL code like vector<> is defined */
/* #undef STL_NAMESPACE */
/* location of source code */
#define TEST_SRC_DIR ""
/* Define to necessary thread-local storage attribute. */
/* #undef GLOG_THREAD_LOCAL_STORAGE */
/* Check whether aligned_storage and alignof present */
#define HAVE_ALIGNED_STORAGE 1
/* Version number of package */
/* #undef VERSION */
#ifdef GLOG_BAZEL_BUILD
/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved:
* https://github.com/bazelbuild/bazel/issues/3979 */
#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE {
#define _END_GOOGLE_NAMESPACE_ }
#else
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
#endif
#endif // GLOG_CONFIG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
// Copyright (c) 2006, 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.
//
// Author: Maxim Lifantsev
//
// Thread-safe logging routines that do not allocate any memory or
// acquire any locks, and can therefore be used by low-level memory
// allocation and synchronization code.
#ifndef BASE_RAW_LOGGING_H_
#define BASE_RAW_LOGGING_H_
#include <time.h>
namespace google {
#include "glog/log_severity.h"
#include "glog/vlog_is_on.h"
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GOOGLE_GLOG_DLL_DECL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
# else
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
// This is similar to LOG(severity) << format... and VLOG(level) << format..,
// but
// * it is to be used ONLY by low-level modules that can't use normal LOG()
// * it is desiged to be a low-level logger that does not allocate any
// memory and does not need any locks, hence:
// * it logs straight and ONLY to STDERR w/o buffering
// * it uses an explicit format and arguments list
// * it will silently chop off really long message strings
// Usage example:
// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
// RAW_VLOG(3, "status is %i", status);
// These will print an almost standard log lines like this to stderr only:
// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
// I0821 211317 file.cc:142] RAW: status is 20
#define RAW_LOG(severity, ...) \
do { \
switch (google::GLOG_ ## severity) { \
case 0: \
RAW_LOG_INFO(__VA_ARGS__); \
break; \
case 1: \
RAW_LOG_WARNING(__VA_ARGS__); \
break; \
case 2: \
RAW_LOG_ERROR(__VA_ARGS__); \
break; \
case 3: \
RAW_LOG_FATAL(__VA_ARGS__); \
break; \
default: \
break; \
} \
} while (0)
// The following STRIP_LOG testing is performed in the header file so that it's
// possible to completely compile out the logging code and the log messages.
#if STRIP_LOG == 0
#define RAW_VLOG(verboselevel, ...) \
do { \
if (VLOG_IS_ON(verboselevel)) { \
RAW_LOG_INFO(__VA_ARGS__); \
} \
} while (0)
#else
#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if STRIP_LOG == 0
#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if STRIP_LOG <= 1
#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 1
#if STRIP_LOG <= 2
#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 2
#if STRIP_LOG <= 3
#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_FATAL(...) \
do { \
google::RawLogStub__(0, __VA_ARGS__); \
exit(1); \
} while (0)
#endif // STRIP_LOG <= 3
// Similar to CHECK(condition) << message,
// but for low-level modules: we use only RAW_LOG that does not allocate memory.
// We do not want to provide args list here to encourage this usage:
// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
// so that the args are not computed when not needed.
#define RAW_CHECK(condition, message) \
do { \
if (!(condition)) { \
RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
} \
} while (0)
// Debug versions of RAW_LOG and RAW_CHECK
#ifndef NDEBUG
#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
#else // NDEBUG
#define RAW_DLOG(severity, ...) \
while (false) \
RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) \
while (false) \
RAW_CHECK(condition, message)
#endif // NDEBUG
// Stub log function used to work around for unused variable warnings when
// building with STRIP_LOG > 0.
static inline void RawLogStub__(int /* ignored */, ...) {
}
// Helper function to implement RAW_LOG and RAW_VLOG
// Logs format... at "severity" level, reporting it
// as called from file:line.
// This does not allocate memory or acquire locks.
GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
const char* file,
int line,
const char* format, ...)
;
}
#endif // BASE_RAW_LOGGING_H_

View File

@ -0,0 +1,220 @@
// Copyright (c) 2003, 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.
//
// Stream output operators for STL containers; to be used for logging *only*.
// Inclusion of this file lets you do:
//
// list<string> x;
// LOG(INFO) << "data: " << x;
// vector<int> v1, v2;
// CHECK_EQ(v1, v2);
//
// If you want to use this header file with hash maps or slist, you
// need to define macros before including this file:
//
// - GLOG_STL_LOGGING_FOR_UNORDERED - <unordered_map> and <unordered_set>
// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <ext/slist>
//
#ifndef UTIL_GTL_STL_LOGGING_INL_H_
#define UTIL_GTL_STL_LOGGING_INL_H_
#if !1
# error We do not support stl_logging for this compiler
#endif
#include <deque>
#include <list>
#include <map>
#include <ostream>
#include <set>
#include <utility>
#include <vector>
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
# include <unordered_map>
# include <unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
# include <tr1/unordered_map>
# include <tr1/unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
# include <ext/hash_set>
# include <ext/hash_map>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
# include <ext/slist>
#endif
// Forward declare these two, and define them after all the container streams
// operators so that we can recurse from pair -> container -> container -> pair
// properly.
template<class First, class Second>
std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
namespace google {
template<class Iter>
void PrintSequence(std::ostream& out, Iter begin, Iter end);
}
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
template<class T1, class T2> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_TWO_ARG_CONTAINER(std::vector)
OUTPUT_TWO_ARG_CONTAINER(std::deque)
OUTPUT_TWO_ARG_CONTAINER(std::list)
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
#endif
#undef OUTPUT_TWO_ARG_CONTAINER
#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_THREE_ARG_CONTAINER(std::set)
OUTPUT_THREE_ARG_CONTAINER(std::multiset)
#undef OUTPUT_THREE_ARG_CONTAINER
#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3, class T4> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3, T4>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_FOUR_ARG_CONTAINER(std::map)
OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
#endif
#undef OUTPUT_FOUR_ARG_CONTAINER
#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3, class T4, class T5> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3, T4, T5>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
#endif
#undef OUTPUT_FIVE_ARG_CONTAINER
template<class First, class Second>
inline std::ostream& operator<<(std::ostream& out,
const std::pair<First, Second>& p) {
out << '(' << p.first << ", " << p.second << ')';
return out;
}
namespace google {
template<class Iter>
inline void PrintSequence(std::ostream& out, Iter begin, Iter end) {
// Output at most 100 elements -- appropriate if used for logging.
for (int i = 0; begin != end && i < 100; ++i, ++begin) {
if (i > 0) out << ' ';
out << *begin;
}
if (begin != end) {
out << " ...";
}
}
}
// Note that this is technically undefined behavior! We are adding things into
// the std namespace for a reason though -- we are providing new operations on
// types which are themselves defined with this namespace. Without this, these
// operator overloads cannot be found via ADL. If these definitions are not
// found via ADL, they must be #included before they're used, which requires
// this header to be included before apparently independent other headers.
//
// For example, base/logging.h defines various template functions to implement
// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
// It does so via the function template MakeCheckOpValueString:
// template<class T>
// void MakeCheckOpValueString(strstream* ss, const T& v) {
// (*ss) << v;
// }
// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
// find these operator definitions via ADL.
//
// Even this solution has problems -- it may pull unintended operators into the
// namespace as well, allowing them to also be found via ADL, and creating code
// that only works with a particular order of includes. Long term, we need to
// move all of the *definitions* into namespace std, bet we need to ensure no
// one references them first. This lets us take that step. We cannot define them
// in both because that would create ambiguous overloads when both are found.
namespace std { using ::operator<<; }
#endif // UTIL_GTL_STL_LOGGING_INL_H_

View File

@ -0,0 +1,129 @@
// Copyright (c) 1999, 2007, 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.
//
// Author: Ray Sidney and many others
//
// Defines the VLOG_IS_ON macro that controls the variable-verbosity
// conditional logging.
//
// It's used by VLOG and VLOG_IF in logging.h
// and by RAW_VLOG in raw_logging.h to trigger the logging.
//
// It can also be used directly e.g. like this:
// if (VLOG_IS_ON(2)) {
// // do some logging preparation and logging
// // that can't be accomplished e.g. via just VLOG(2) << ...;
// }
//
// The truth value that VLOG_IS_ON(level) returns is determined by
// the three verbosity level flags:
// --v=<n> Gives the default maximal active V-logging level;
// 0 is the default.
// Normally positive values are used for V-logging levels.
// --vmodule=<str> Gives the per-module maximal V-logging levels to override
// the value given by --v.
// E.g. "my_module=2,foo*=3" would change the logging level
// for all code in source files "my_module.*" and "foo*.*"
// ("-inl" suffixes are also disregarded for this matching).
//
// SetVLOGLevel helper function is provided to do limited dynamic control over
// V-logging by overriding the per-module settings given via --vmodule flag.
//
// CAVEAT: --vmodule functionality is not available in non gcc compilers.
//
#ifndef BASE_VLOG_IS_ON_H_
#define BASE_VLOG_IS_ON_H_
#include "glog/log_severity.h"
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GOOGLE_GLOG_DLL_DECL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
# else
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
#if defined(__GNUC__)
// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
// (Normally) the first time every VLOG_IS_ON(n) site is hit,
// we determine what variable will dynamically control logging at this site:
// it's either FLAGS_v or an appropriate internal variable
// matching the current source file that represents results of
// parsing of --vmodule flag and/or SetVLOGLevel calls.
#define VLOG_IS_ON(verboselevel) \
__extension__ \
({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \
google::int32 verbose_level__ = (verboselevel); \
(*vlocal__ >= verbose_level__) && \
((vlocal__ != &google::kLogSiteUninitialized) || \
(google::InitVLOG3__(&vlocal__, &FLAGS_v, \
__FILE__, verbose_level__))); })
#else
// GNU extensions not available, so we do not support --vmodule.
// Dynamic value of FLAGS_v always controls the logging level.
#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
#endif
// Set VLOG(_IS_ON) level for module_pattern to log_level.
// This lets us dynamically control what is normally set by the --vmodule flag.
// Returns the level that previously applied to module_pattern.
// NOTE: To change the log level for VLOG(_IS_ON) sites
// that have already executed after/during InitGoogleLogging,
// one needs to supply the exact --vmodule pattern that applied to them.
// (If no --vmodule pattern applied to them
// the value of FLAGS_v will continue to control them.)
extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
int log_level);
// Various declarations needed for VLOG_IS_ON above: =========================
// Special value used to indicate that a VLOG_IS_ON site has not been
// initialized. We make this a large value, so the common-case check
// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
// passes in such cases and InitVLOG3__ is then triggered.
extern google::int32 kLogSiteUninitialized;
// Helper routine which determines the logging info for a particalur VLOG site.
// site_flag is the address of the site-local pointer to the controlling
// verbosity level
// site_default is the default to use for *site_flag
// fname is the current source file name
// verbose_level is the argument to VLOG_IS_ON
// We will return the return value for VLOG_IS_ON
// and if possible set *site_flag appropriately.
extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
google::int32** site_flag,
google::int32* site_default,
const char* fname,
google::int32 verbose_level);
#endif // BASE_VLOG_IS_ON_H_

View File

@ -0,0 +1,216 @@
#ifndef GLOG_CONFIG_H
#define GLOG_CONFIG_H
/* define if glog doesn't use RTTI */
/* #undef DISABLE_RTTI */
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE google
/* Define if you have the `dladdr' function */
#define HAVE_DLADDR
/* Define if you have the `snprintf' function */
#define HAVE_SNPRINTF
/* Define to 1 if you have the <dlfcn.h> header file. */
#define HAVE_DLFCN_H
/* Define to 1 if you have the <execinfo.h> header file. */
#define HAVE_EXECINFO_H
/* Define if you have the `fcntl' function */
#define HAVE_FCNTL
/* Define to 1 if you have the <glob.h> header file. */
#define HAVE_GLOB_H
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
/* #undef HAVE_LIBPTHREAD */
/* Define to 1 if you have the <libunwind.h> header file. */
#define HAVE_LIBUNWIND_H
/* define if you have google gflags library */
#define HAVE_LIB_GFLAGS
/* define if you have google gmock library */
/* #undef HAVE_LIB_GMOCK */
/* define if you have google gtest library */
/* #undef HAVE_LIB_GTEST */
/* define if you have libunwind */
/* #undef HAVE_LIB_UNWIND */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
/* define to disable multithreading support. */
/* #undef NO_THREADS */
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES
/* Define if you have the 'pread' function */
#define HAVE_PREAD
/* Define if you have POSIX threads libraries and header files. */
#define HAVE_PTHREAD
/* Define to 1 if you have the <pwd.h> header file. */
#define HAVE_PWD_H
/* Define if you have the 'pwrite' function */
#define HAVE_PWRITE
/* define if the compiler implements pthread_rwlock_* */
#define HAVE_RWLOCK
/* Define if you have the 'sigaction' function */
#define HAVE_SIGACTION
/* Define if you have the `sigaltstack' function */
/* #undef HAVE_SIGALTSTACK */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
#define HAVE_STRINGS_H
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define to 1 if you have the <syscall.h> header file. */
/* #undef HAVE_SYSCALL_H */
/* Define to 1 if you have the <syslog.h> header file. */
#define HAVE_SYSLOG_H
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/syscall.h> header file. */
#define HAVE_SYS_SYSCALL_H
/* Define to 1 if you have the <sys/time.h> header file. */
#define HAVE_SYS_TIME_H
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/ucontext.h> header file. */
/* #undef HAVE_SYS_UCONTEXT_H */
/* Define to 1 if you have the <sys/utsname.h> header file. */
#define HAVE_SYS_UTSNAME_H
/* Define to 1 if you have the <ucontext.h> header file. */
/* #undef HAVE_UCONTEXT_H */
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <unwind.h> header file. */
#define HAVE_UNWIND_H 1
/* define if the compiler supports using expression for operator */
#define HAVE_USING_OPERATOR
/* define if your compiler has __attribute__ */
#define HAVE___ATTRIBUTE__
/* define if your compiler has __builtin_expect */
#define HAVE___BUILTIN_EXPECT 1
/* define if your compiler has __sync_val_compare_and_swap */
#define HAVE___SYNC_VAL_COMPARE_AND_SWAP
/* define if symbolize support is available */
#define HAVE_SYMBOLIZE
/* define if localtime_r is available in time.h */
#define HAVE_LOCALTIME_R
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* #undef LT_OBJDIR */
/* Name of package */
/* #undef PACKAGE */
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the home page for this package. */
/* #undef PACKAGE_URL */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* How to access the PC from a struct ucontext */
/* #undef PC_FROM_UCONTEXT */
/* define if we should print raw pc values on symbolization failure. */
/* #undef PRINT_UNSYMBOLIZED_STACK_TRACES */
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 8
/* Define to 1 if you have the ANSI C header files. */
/* #undef STDC_HEADERS */
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* location of source code */
#define TEST_SRC_DIR ""
/* Define to necessary thread-local storage attribute. */
/* #undef GLOG_THREAD_LOCAL_STORAGE */
/* Check whether aligned_storage and alignof present */
/* #undef HAVE_ALIGNED_STORAGE */
/* Version number of package */
/* #undef VERSION */
#ifdef GLOG_BAZEL_BUILD
/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved:
* https://github.com/bazelbuild/bazel/issues/3979 */
#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE {
#define _END_GOOGLE_NAMESPACE_ }
#else
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
#endif
#endif // GLOG_CONFIG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
// Copyright (c) 2006, 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.
//
// Author: Maxim Lifantsev
//
// Thread-safe logging routines that do not allocate any memory or
// acquire any locks, and can therefore be used by low-level memory
// allocation and synchronization code.
#ifndef BASE_RAW_LOGGING_H_
#define BASE_RAW_LOGGING_H_
#include <time.h>
namespace google {
#include "glog/log_severity.h"
#include "glog/vlog_is_on.h"
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GOOGLE_GLOG_DLL_DECL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
# else
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
// This is similar to LOG(severity) << format... and VLOG(level) << format..,
// but
// * it is to be used ONLY by low-level modules that can't use normal LOG()
// * it is desiged to be a low-level logger that does not allocate any
// memory and does not need any locks, hence:
// * it logs straight and ONLY to STDERR w/o buffering
// * it uses an explicit format and arguments list
// * it will silently chop off really long message strings
// Usage example:
// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
// RAW_VLOG(3, "status is %i", status);
// These will print an almost standard log lines like this to stderr only:
// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
// I0821 211317 file.cc:142] RAW: status is 20
#define RAW_LOG(severity, ...) \
do { \
switch (google::GLOG_ ## severity) { \
case 0: \
RAW_LOG_INFO(__VA_ARGS__); \
break; \
case 1: \
RAW_LOG_WARNING(__VA_ARGS__); \
break; \
case 2: \
RAW_LOG_ERROR(__VA_ARGS__); \
break; \
case 3: \
RAW_LOG_FATAL(__VA_ARGS__); \
break; \
default: \
break; \
} \
} while (0)
// The following STRIP_LOG testing is performed in the header file so that it's
// possible to completely compile out the logging code and the log messages.
#if STRIP_LOG == 0
#define RAW_VLOG(verboselevel, ...) \
do { \
if (VLOG_IS_ON(verboselevel)) { \
RAW_LOG_INFO(__VA_ARGS__); \
} \
} while (0)
#else
#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if STRIP_LOG == 0
#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if STRIP_LOG <= 1
#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 1
#if STRIP_LOG <= 2
#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 2
#if STRIP_LOG <= 3
#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_FATAL(...) \
do { \
google::RawLogStub__(0, __VA_ARGS__); \
exit(1); \
} while (0)
#endif // STRIP_LOG <= 3
// Similar to CHECK(condition) << message,
// but for low-level modules: we use only RAW_LOG that does not allocate memory.
// We do not want to provide args list here to encourage this usage:
// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
// so that the args are not computed when not needed.
#define RAW_CHECK(condition, message) \
do { \
if (!(condition)) { \
RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
} \
} while (0)
// Debug versions of RAW_LOG and RAW_CHECK
#ifndef NDEBUG
#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
#else // NDEBUG
#define RAW_DLOG(severity, ...) \
while (false) \
RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) \
while (false) \
RAW_CHECK(condition, message)
#endif // NDEBUG
// Stub log function used to work around for unused variable warnings when
// building with STRIP_LOG > 0.
static inline void RawLogStub__(int /* ignored */, ...) {
}
// Helper function to implement RAW_LOG and RAW_VLOG
// Logs format... at "severity" level, reporting it
// as called from file:line.
// This does not allocate memory or acquire locks.
GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
const char* file,
int line,
const char* format, ...)
;
}
#endif // BASE_RAW_LOGGING_H_

View File

@ -0,0 +1,220 @@
// Copyright (c) 2003, 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.
//
// Stream output operators for STL containers; to be used for logging *only*.
// Inclusion of this file lets you do:
//
// list<string> x;
// LOG(INFO) << "data: " << x;
// vector<int> v1, v2;
// CHECK_EQ(v1, v2);
//
// If you want to use this header file with hash maps or slist, you
// need to define macros before including this file:
//
// - GLOG_STL_LOGGING_FOR_UNORDERED - <unordered_map> and <unordered_set>
// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <ext/slist>
//
#ifndef UTIL_GTL_STL_LOGGING_INL_H_
#define UTIL_GTL_STL_LOGGING_INL_H_
#if !1
# error We do not support stl_logging for this compiler
#endif
#include <deque>
#include <list>
#include <map>
#include <ostream>
#include <set>
#include <utility>
#include <vector>
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
# include <unordered_map>
# include <unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
# include <tr1/unordered_map>
# include <tr1/unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
# include <ext/hash_set>
# include <ext/hash_map>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
# include <ext/slist>
#endif
// Forward declare these two, and define them after all the container streams
// operators so that we can recurse from pair -> container -> container -> pair
// properly.
template<class First, class Second>
std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
namespace google {
template<class Iter>
void PrintSequence(std::ostream& out, Iter begin, Iter end);
}
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
template<class T1, class T2> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_TWO_ARG_CONTAINER(std::vector)
OUTPUT_TWO_ARG_CONTAINER(std::deque)
OUTPUT_TWO_ARG_CONTAINER(std::list)
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
#endif
#undef OUTPUT_TWO_ARG_CONTAINER
#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_THREE_ARG_CONTAINER(std::set)
OUTPUT_THREE_ARG_CONTAINER(std::multiset)
#undef OUTPUT_THREE_ARG_CONTAINER
#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3, class T4> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3, T4>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_FOUR_ARG_CONTAINER(std::map)
OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
#endif
#undef OUTPUT_FOUR_ARG_CONTAINER
#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3, class T4, class T5> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3, T4, T5>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
#endif
#undef OUTPUT_FIVE_ARG_CONTAINER
template<class First, class Second>
inline std::ostream& operator<<(std::ostream& out,
const std::pair<First, Second>& p) {
out << '(' << p.first << ", " << p.second << ')';
return out;
}
namespace google {
template<class Iter>
inline void PrintSequence(std::ostream& out, Iter begin, Iter end) {
// Output at most 100 elements -- appropriate if used for logging.
for (int i = 0; begin != end && i < 100; ++i, ++begin) {
if (i > 0) out << ' ';
out << *begin;
}
if (begin != end) {
out << " ...";
}
}
}
// Note that this is technically undefined behavior! We are adding things into
// the std namespace for a reason though -- we are providing new operations on
// types which are themselves defined with this namespace. Without this, these
// operator overloads cannot be found via ADL. If these definitions are not
// found via ADL, they must be #included before they're used, which requires
// this header to be included before apparently independent other headers.
//
// For example, base/logging.h defines various template functions to implement
// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
// It does so via the function template MakeCheckOpValueString:
// template<class T>
// void MakeCheckOpValueString(strstream* ss, const T& v) {
// (*ss) << v;
// }
// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
// find these operator definitions via ADL.
//
// Even this solution has problems -- it may pull unintended operators into the
// namespace as well, allowing them to also be found via ADL, and creating code
// that only works with a particular order of includes. Long term, we need to
// move all of the *definitions* into namespace std, bet we need to ensure no
// one references them first. This lets us take that step. We cannot define them
// in both because that would create ambiguous overloads when both are found.
namespace std { using ::operator<<; }
#endif // UTIL_GTL_STL_LOGGING_INL_H_

View File

@ -0,0 +1,129 @@
// Copyright (c) 1999, 2007, 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.
//
// Author: Ray Sidney and many others
//
// Defines the VLOG_IS_ON macro that controls the variable-verbosity
// conditional logging.
//
// It's used by VLOG and VLOG_IF in logging.h
// and by RAW_VLOG in raw_logging.h to trigger the logging.
//
// It can also be used directly e.g. like this:
// if (VLOG_IS_ON(2)) {
// // do some logging preparation and logging
// // that can't be accomplished e.g. via just VLOG(2) << ...;
// }
//
// The truth value that VLOG_IS_ON(level) returns is determined by
// the three verbosity level flags:
// --v=<n> Gives the default maximal active V-logging level;
// 0 is the default.
// Normally positive values are used for V-logging levels.
// --vmodule=<str> Gives the per-module maximal V-logging levels to override
// the value given by --v.
// E.g. "my_module=2,foo*=3" would change the logging level
// for all code in source files "my_module.*" and "foo*.*"
// ("-inl" suffixes are also disregarded for this matching).
//
// SetVLOGLevel helper function is provided to do limited dynamic control over
// V-logging by overriding the per-module settings given via --vmodule flag.
//
// CAVEAT: --vmodule functionality is not available in non gcc compilers.
//
#ifndef BASE_VLOG_IS_ON_H_
#define BASE_VLOG_IS_ON_H_
#include "glog/log_severity.h"
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GOOGLE_GLOG_DLL_DECL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
# else
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
#if defined(__GNUC__)
// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
// (Normally) the first time every VLOG_IS_ON(n) site is hit,
// we determine what variable will dynamically control logging at this site:
// it's either FLAGS_v or an appropriate internal variable
// matching the current source file that represents results of
// parsing of --vmodule flag and/or SetVLOGLevel calls.
#define VLOG_IS_ON(verboselevel) \
__extension__ \
({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \
google::int32 verbose_level__ = (verboselevel); \
(*vlocal__ >= verbose_level__) && \
((vlocal__ != &google::kLogSiteUninitialized) || \
(google::InitVLOG3__(&vlocal__, &FLAGS_v, \
__FILE__, verbose_level__))); })
#else
// GNU extensions not available, so we do not support --vmodule.
// Dynamic value of FLAGS_v always controls the logging level.
#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
#endif
// Set VLOG(_IS_ON) level for module_pattern to log_level.
// This lets us dynamically control what is normally set by the --vmodule flag.
// Returns the level that previously applied to module_pattern.
// NOTE: To change the log level for VLOG(_IS_ON) sites
// that have already executed after/during InitGoogleLogging,
// one needs to supply the exact --vmodule pattern that applied to them.
// (If no --vmodule pattern applied to them
// the value of FLAGS_v will continue to control them.)
extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
int log_level);
// Various declarations needed for VLOG_IS_ON above: =========================
// Special value used to indicate that a VLOG_IS_ON site has not been
// initialized. We make this a large value, so the common-case check
// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
// passes in such cases and InitVLOG3__ is then triggered.
extern google::int32 kLogSiteUninitialized;
// Helper routine which determines the logging info for a particalur VLOG site.
// site_flag is the address of the site-local pointer to the controlling
// verbosity level
// site_default is the default to use for *site_flag
// fname is the current source file name
// verbose_level is the argument to VLOG_IS_ON
// We will return the return value for VLOG_IS_ON
// and if possible set *site_flag appropriately.
extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
google::int32** site_flag,
google::int32* site_default,
const char* fname,
google::int32 verbose_level);
#endif // BASE_VLOG_IS_ON_H_

View File

@ -0,0 +1,216 @@
#ifndef GLOG_CONFIG_H
#define GLOG_CONFIG_H
/* define if glog doesn't use RTTI */
/* #undef DISABLE_RTTI */
/* Namespace for Google classes */
#define GOOGLE_NAMESPACE google
/* Define if you have the `dladdr' function */
/* #undef HAVE_DLADDR */
/* Define if you have the `snprintf' function */
#define HAVE_SNPRINTF
/* Define to 1 if you have the <dlfcn.h> header file. */
/* #undef HAVE_DLFCN_H */
/* Define to 1 if you have the <execinfo.h> header file. */
/* #undef HAVE_EXECINFO_H */
/* Define if you have the `fcntl' function */
/* #undef HAVE_FCNTL */
/* Define to 1 if you have the <glob.h> header file. */
/* #undef HAVE_GLOB_H */
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
/* Define to 1 if you have the `pthread' library (-lpthread). */
/* #undef HAVE_LIBPTHREAD */
/* Define to 1 if you have the <libunwind.h> header file. */
/* #undef HAVE_LIBUNWIND_H */
/* define if you have google gflags library */
#define HAVE_LIB_GFLAGS
/* define if you have google gmock library */
/* #undef HAVE_LIB_GMOCK */
/* define if you have google gtest library */
/* #undef HAVE_LIB_GTEST */
/* define if you have libunwind */
/* #undef HAVE_LIB_UNWIND */
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H
/* define to disable multithreading support. */
/* #undef NO_THREADS */
/* define if the compiler implements namespaces */
#define HAVE_NAMESPACES
/* Define if you have the 'pread' function */
/* #undef HAVE_PREAD */
/* Define if you have POSIX threads libraries and header files. */
/* #undef HAVE_PTHREAD */
/* Define to 1 if you have the <pwd.h> header file. */
/* #undef HAVE_PWD_H */
/* Define if you have the 'pwrite' function */
/* #undef HAVE_PWRITE */
/* define if the compiler implements pthread_rwlock_* */
/* #undef HAVE_RWLOCK */
/* Define if you have the 'sigaction' function */
/* #undef HAVE_SIGACTION */
/* Define if you have the `sigaltstack' function */
/* #undef HAVE_SIGALTSTACK */
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H
/* Define to 1 if you have the <strings.h> header file. */
/* #undef HAVE_STRINGS_H */
/* Define to 1 if you have the <string.h> header file. */
#define HAVE_STRING_H
/* Define to 1 if you have the <syscall.h> header file. */
/* #undef HAVE_SYSCALL_H */
/* Define to 1 if you have the <syslog.h> header file. */
/* #undef HAVE_SYSLOG_H */
/* Define to 1 if you have the <sys/stat.h> header file. */
#define HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/syscall.h> header file. */
/* #undef HAVE_SYS_SYSCALL_H */
/* Define to 1 if you have the <sys/time.h> header file. */
/* #undef HAVE_SYS_TIME_H */
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <sys/ucontext.h> header file. */
/* #undef HAVE_SYS_UCONTEXT_H */
/* Define to 1 if you have the <sys/utsname.h> header file. */
/* #undef HAVE_SYS_UTSNAME_H */
/* Define to 1 if you have the <ucontext.h> header file. */
/* #undef HAVE_UCONTEXT_H */
/* Define to 1 if you have the <unistd.h> header file. */
/* #undef HAVE_UNISTD_H */
/* Define to 1 if you have the <unwind.h> header file. */
/* #undef HAVE_UNWIND_H */
/* define if the compiler supports using expression for operator */
#define HAVE_USING_OPERATOR
/* define if your compiler has __attribute__ */
/* #undef HAVE___ATTRIBUTE__ */
/* define if your compiler has __builtin_expect */
/* #undef HAVE___BUILTIN_EXPECT */
/* define if your compiler has __sync_val_compare_and_swap */
/* #undef HAVE___SYNC_VAL_COMPARE_AND_SWAP */
/* define if symbolize support is available */
#define HAVE_SYMBOLIZE
/* define if localtime_r is available in time.h */
/* #undef HAVE_LOCALTIME_R */
/* Define to the sub-directory in which libtool stores uninstalled libraries.
*/
/* #undef LT_OBJDIR */
/* Name of package */
/* #undef PACKAGE */
/* Define to the address where bug reports for this package should be sent. */
/* #undef PACKAGE_BUGREPORT */
/* Define to the full name of this package. */
/* #undef PACKAGE_NAME */
/* Define to the full name and version of this package. */
/* #undef PACKAGE_STRING */
/* Define to the one symbol short name of this package. */
/* #undef PACKAGE_TARNAME */
/* Define to the home page for this package. */
/* #undef PACKAGE_URL */
/* Define to the version of this package. */
/* #undef PACKAGE_VERSION */
/* How to access the PC from a struct ucontext */
/* #undef PC_FROM_UCONTEXT */
/* define if we should print raw pc values on symbolization failure. */
/* #undef PRINT_UNSYMBOLIZED_STACK_TRACES */
/* Define to necessary symbol if this constant uses a non-standard name on
your system. */
/* #undef PTHREAD_CREATE_JOINABLE */
/* The size of `void *', as computed by sizeof. */
#define SIZEOF_VOID_P 8
/* Define to 1 if you have the ANSI C header files. */
/* #undef STDC_HEADERS */
/* the namespace where STL code like vector<> is defined */
#define STL_NAMESPACE std
/* location of source code */
#define TEST_SRC_DIR ""
/* Define to necessary thread-local storage attribute. */
/* #undef GLOG_THREAD_LOCAL_STORAGE */
/* Check whether aligned_storage and alignof present */
#define HAVE_ALIGNED_STORAGE 1
/* Version number of package */
/* #undef VERSION */
#ifdef GLOG_BAZEL_BUILD
/* TODO(rodrigoq): remove this workaround once bazel#3979 is resolved:
* https://github.com/bazelbuild/bazel/issues/3979 */
#define _START_GOOGLE_NAMESPACE_ namespace GOOGLE_NAMESPACE {
#define _END_GOOGLE_NAMESPACE_ }
#else
/* Stops putting the code inside the Google namespace */
#define _END_GOOGLE_NAMESPACE_ }
/* Puts following code inside the Google namespace */
#define _START_GOOGLE_NAMESPACE_ namespace google {
#endif
#endif // GLOG_CONFIG_H

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,180 @@
// Copyright (c) 2006, 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.
//
// Author: Maxim Lifantsev
//
// Thread-safe logging routines that do not allocate any memory or
// acquire any locks, and can therefore be used by low-level memory
// allocation and synchronization code.
#ifndef BASE_RAW_LOGGING_H_
#define BASE_RAW_LOGGING_H_
#include <time.h>
namespace google {
#include "glog/log_severity.h"
#include "glog/vlog_is_on.h"
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GOOGLE_GLOG_DLL_DECL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
# else
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
// This is similar to LOG(severity) << format... and VLOG(level) << format..,
// but
// * it is to be used ONLY by low-level modules that can't use normal LOG()
// * it is desiged to be a low-level logger that does not allocate any
// memory and does not need any locks, hence:
// * it logs straight and ONLY to STDERR w/o buffering
// * it uses an explicit format and arguments list
// * it will silently chop off really long message strings
// Usage example:
// RAW_LOG(ERROR, "Failed foo with %i: %s", status, error);
// RAW_VLOG(3, "status is %i", status);
// These will print an almost standard log lines like this to stderr only:
// E0821 211317 file.cc:123] RAW: Failed foo with 22: bad_file
// I0821 211317 file.cc:142] RAW: status is 20
#define RAW_LOG(severity, ...) \
do { \
switch (google::GLOG_ ## severity) { \
case 0: \
RAW_LOG_INFO(__VA_ARGS__); \
break; \
case 1: \
RAW_LOG_WARNING(__VA_ARGS__); \
break; \
case 2: \
RAW_LOG_ERROR(__VA_ARGS__); \
break; \
case 3: \
RAW_LOG_FATAL(__VA_ARGS__); \
break; \
default: \
break; \
} \
} while (0)
// The following STRIP_LOG testing is performed in the header file so that it's
// possible to completely compile out the logging code and the log messages.
#if STRIP_LOG == 0
#define RAW_VLOG(verboselevel, ...) \
do { \
if (VLOG_IS_ON(verboselevel)) { \
RAW_LOG_INFO(__VA_ARGS__); \
} \
} while (0)
#else
#define RAW_VLOG(verboselevel, ...) RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if STRIP_LOG == 0
#define RAW_LOG_INFO(...) google::RawLog__(google::GLOG_INFO, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_INFO(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG == 0
#if STRIP_LOG <= 1
#define RAW_LOG_WARNING(...) google::RawLog__(google::GLOG_WARNING, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_WARNING(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 1
#if STRIP_LOG <= 2
#define RAW_LOG_ERROR(...) google::RawLog__(google::GLOG_ERROR, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_ERROR(...) google::RawLogStub__(0, __VA_ARGS__)
#endif // STRIP_LOG <= 2
#if STRIP_LOG <= 3
#define RAW_LOG_FATAL(...) google::RawLog__(google::GLOG_FATAL, \
__FILE__, __LINE__, __VA_ARGS__)
#else
#define RAW_LOG_FATAL(...) \
do { \
google::RawLogStub__(0, __VA_ARGS__); \
exit(1); \
} while (0)
#endif // STRIP_LOG <= 3
// Similar to CHECK(condition) << message,
// but for low-level modules: we use only RAW_LOG that does not allocate memory.
// We do not want to provide args list here to encourage this usage:
// if (!cond) RAW_LOG(FATAL, "foo ...", hard_to_compute_args);
// so that the args are not computed when not needed.
#define RAW_CHECK(condition, message) \
do { \
if (!(condition)) { \
RAW_LOG(FATAL, "Check %s failed: %s", #condition, message); \
} \
} while (0)
// Debug versions of RAW_LOG and RAW_CHECK
#ifndef NDEBUG
#define RAW_DLOG(severity, ...) RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) RAW_CHECK(condition, message)
#else // NDEBUG
#define RAW_DLOG(severity, ...) \
while (false) \
RAW_LOG(severity, __VA_ARGS__)
#define RAW_DCHECK(condition, message) \
while (false) \
RAW_CHECK(condition, message)
#endif // NDEBUG
// Stub log function used to work around for unused variable warnings when
// building with STRIP_LOG > 0.
static inline void RawLogStub__(int /* ignored */, ...) {
}
// Helper function to implement RAW_LOG and RAW_VLOG
// Logs format... at "severity" level, reporting it
// as called from file:line.
// This does not allocate memory or acquire locks.
GOOGLE_GLOG_DLL_DECL void RawLog__(LogSeverity severity,
const char* file,
int line,
const char* format, ...)
;
}
#endif // BASE_RAW_LOGGING_H_

View File

@ -0,0 +1,220 @@
// Copyright (c) 2003, 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.
//
// Stream output operators for STL containers; to be used for logging *only*.
// Inclusion of this file lets you do:
//
// list<string> x;
// LOG(INFO) << "data: " << x;
// vector<int> v1, v2;
// CHECK_EQ(v1, v2);
//
// If you want to use this header file with hash maps or slist, you
// need to define macros before including this file:
//
// - GLOG_STL_LOGGING_FOR_UNORDERED - <unordered_map> and <unordered_set>
// - GLOG_STL_LOGGING_FOR_TR1_UNORDERED - <tr1/unordered_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_HASH - <ext/hash_(map|set)>
// - GLOG_STL_LOGGING_FOR_EXT_SLIST - <ext/slist>
//
#ifndef UTIL_GTL_STL_LOGGING_INL_H_
#define UTIL_GTL_STL_LOGGING_INL_H_
#if !1
# error We do not support stl_logging for this compiler
#endif
#include <deque>
#include <list>
#include <map>
#include <ostream>
#include <set>
#include <utility>
#include <vector>
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
# include <unordered_map>
# include <unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
# include <tr1/unordered_map>
# include <tr1/unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
# include <ext/hash_set>
# include <ext/hash_map>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
# include <ext/slist>
#endif
// Forward declare these two, and define them after all the container streams
// operators so that we can recurse from pair -> container -> container -> pair
// properly.
template<class First, class Second>
std::ostream& operator<<(std::ostream& out, const std::pair<First, Second>& p);
namespace google {
template<class Iter>
void PrintSequence(std::ostream& out, Iter begin, Iter end);
}
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
template<class T1, class T2> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_TWO_ARG_CONTAINER(std::vector)
OUTPUT_TWO_ARG_CONTAINER(std::deque)
OUTPUT_TWO_ARG_CONTAINER(std::list)
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
#endif
#undef OUTPUT_TWO_ARG_CONTAINER
#define OUTPUT_THREE_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_THREE_ARG_CONTAINER(std::set)
OUTPUT_THREE_ARG_CONTAINER(std::multiset)
#undef OUTPUT_THREE_ARG_CONTAINER
#define OUTPUT_FOUR_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3, class T4> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3, T4>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
OUTPUT_FOUR_ARG_CONTAINER(std::map)
OUTPUT_FOUR_ARG_CONTAINER(std::multimap)
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
#endif
#undef OUTPUT_FOUR_ARG_CONTAINER
#define OUTPUT_FIVE_ARG_CONTAINER(Sequence) \
template<class T1, class T2, class T3, class T4, class T5> \
inline std::ostream& operator<<(std::ostream& out, \
const Sequence<T1, T2, T3, T4, T5>& seq) { \
google::PrintSequence(out, seq.begin(), seq.end()); \
return out; \
}
#ifdef GLOG_STL_LOGGING_FOR_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
#endif
#undef OUTPUT_FIVE_ARG_CONTAINER
template<class First, class Second>
inline std::ostream& operator<<(std::ostream& out,
const std::pair<First, Second>& p) {
out << '(' << p.first << ", " << p.second << ')';
return out;
}
namespace google {
template<class Iter>
inline void PrintSequence(std::ostream& out, Iter begin, Iter end) {
// Output at most 100 elements -- appropriate if used for logging.
for (int i = 0; begin != end && i < 100; ++i, ++begin) {
if (i > 0) out << ' ';
out << *begin;
}
if (begin != end) {
out << " ...";
}
}
}
// Note that this is technically undefined behavior! We are adding things into
// the std namespace for a reason though -- we are providing new operations on
// types which are themselves defined with this namespace. Without this, these
// operator overloads cannot be found via ADL. If these definitions are not
// found via ADL, they must be #included before they're used, which requires
// this header to be included before apparently independent other headers.
//
// For example, base/logging.h defines various template functions to implement
// CHECK_EQ(x, y) and stream x and y into the log in the event the check fails.
// It does so via the function template MakeCheckOpValueString:
// template<class T>
// void MakeCheckOpValueString(strstream* ss, const T& v) {
// (*ss) << v;
// }
// Because 'glog/logging.h' is included before 'glog/stl_logging.h',
// subsequent CHECK_EQ(v1, v2) for vector<...> typed variable v1 and v2 can only
// find these operator definitions via ADL.
//
// Even this solution has problems -- it may pull unintended operators into the
// namespace as well, allowing them to also be found via ADL, and creating code
// that only works with a particular order of includes. Long term, we need to
// move all of the *definitions* into namespace std, bet we need to ensure no
// one references them first. This lets us take that step. We cannot define them
// in both because that would create ambiguous overloads when both are found.
namespace std { using ::operator<<; }
#endif // UTIL_GTL_STL_LOGGING_INL_H_

View File

@ -0,0 +1,129 @@
// Copyright (c) 1999, 2007, 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.
//
// Author: Ray Sidney and many others
//
// Defines the VLOG_IS_ON macro that controls the variable-verbosity
// conditional logging.
//
// It's used by VLOG and VLOG_IF in logging.h
// and by RAW_VLOG in raw_logging.h to trigger the logging.
//
// It can also be used directly e.g. like this:
// if (VLOG_IS_ON(2)) {
// // do some logging preparation and logging
// // that can't be accomplished e.g. via just VLOG(2) << ...;
// }
//
// The truth value that VLOG_IS_ON(level) returns is determined by
// the three verbosity level flags:
// --v=<n> Gives the default maximal active V-logging level;
// 0 is the default.
// Normally positive values are used for V-logging levels.
// --vmodule=<str> Gives the per-module maximal V-logging levels to override
// the value given by --v.
// E.g. "my_module=2,foo*=3" would change the logging level
// for all code in source files "my_module.*" and "foo*.*"
// ("-inl" suffixes are also disregarded for this matching).
//
// SetVLOGLevel helper function is provided to do limited dynamic control over
// V-logging by overriding the per-module settings given via --vmodule flag.
//
// CAVEAT: --vmodule functionality is not available in non gcc compilers.
//
#ifndef BASE_VLOG_IS_ON_H_
#define BASE_VLOG_IS_ON_H_
#include "glog/log_severity.h"
// Annoying stuff for windows -- makes sure clients can import these functions
#ifndef GOOGLE_GLOG_DLL_DECL
# if defined(_WIN32) && !defined(__CYGWIN__)
# define GOOGLE_GLOG_DLL_DECL __declspec(dllimport)
# else
# define GOOGLE_GLOG_DLL_DECL
# endif
#endif
#if defined(__GNUC__)
// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
// (Normally) the first time every VLOG_IS_ON(n) site is hit,
// we determine what variable will dynamically control logging at this site:
// it's either FLAGS_v or an appropriate internal variable
// matching the current source file that represents results of
// parsing of --vmodule flag and/or SetVLOGLevel calls.
#define VLOG_IS_ON(verboselevel) \
__extension__ \
({ static google::int32* vlocal__ = &google::kLogSiteUninitialized; \
google::int32 verbose_level__ = (verboselevel); \
(*vlocal__ >= verbose_level__) && \
((vlocal__ != &google::kLogSiteUninitialized) || \
(google::InitVLOG3__(&vlocal__, &FLAGS_v, \
__FILE__, verbose_level__))); })
#else
// GNU extensions not available, so we do not support --vmodule.
// Dynamic value of FLAGS_v always controls the logging level.
#define VLOG_IS_ON(verboselevel) (FLAGS_v >= (verboselevel))
#endif
// Set VLOG(_IS_ON) level for module_pattern to log_level.
// This lets us dynamically control what is normally set by the --vmodule flag.
// Returns the level that previously applied to module_pattern.
// NOTE: To change the log level for VLOG(_IS_ON) sites
// that have already executed after/during InitGoogleLogging,
// one needs to supply the exact --vmodule pattern that applied to them.
// (If no --vmodule pattern applied to them
// the value of FLAGS_v will continue to control them.)
extern GOOGLE_GLOG_DLL_DECL int SetVLOGLevel(const char* module_pattern,
int log_level);
// Various declarations needed for VLOG_IS_ON above: =========================
// Special value used to indicate that a VLOG_IS_ON site has not been
// initialized. We make this a large value, so the common-case check
// of "*vlocal__ >= verbose_level__" in VLOG_IS_ON definition
// passes in such cases and InitVLOG3__ is then triggered.
extern google::int32 kLogSiteUninitialized;
// Helper routine which determines the logging info for a particalur VLOG site.
// site_flag is the address of the site-local pointer to the controlling
// verbosity level
// site_default is the default to use for *site_flag
// fname is the current source file name
// verbose_level is the argument to VLOG_IS_ON
// We will return the return value for VLOG_IS_ON
// and if possible set *site_flag appropriately.
extern GOOGLE_GLOG_DLL_DECL bool InitVLOG3__(
google::int32** site_flag,
google::int32* site_default,
const char* fname,
google::int32 verbose_level);
#endif // BASE_VLOG_IS_ON_H_

View File

@ -144,6 +144,7 @@ function(librpmMain)
# This mirrors detection done by autoconf/headers.m4 as CMake code. # This mirrors detection done by autoconf/headers.m4 as CMake code.
# #
if(DEFINED PLATFORM_LINUX) if(DEFINED PLATFORM_LINUX)
include(CheckSymbolExists)
CHECK_SYMBOL_EXISTS(major "sys/mkdev.h" MAJOR_IN_MKDEV) CHECK_SYMBOL_EXISTS(major "sys/mkdev.h" MAJOR_IN_MKDEV)
CHECK_SYMBOL_EXISTS(major "sys/sysmacros.h" MAJOR_IN_SYSMACROS) CHECK_SYMBOL_EXISTS(major "sys/sysmacros.h" MAJOR_IN_SYSMACROS)
if(MAJOR_IN_MKDEV) if(MAJOR_IN_MKDEV)

@ -1 +1 @@
Subproject commit 6afcf545d2ab86d13a3ecb9f656aa81622031f2a Subproject commit f8b3b6de97db63287e4525857cbd39dbee174f9c

View File

@ -14,22 +14,12 @@
#include <boost/noncopyable.hpp> #include <boost/noncopyable.hpp>
#define GFLAGS_DLL_DEFINE_FLAG
#ifndef GFLAGS_DLL_DECLARE_FLAG
#define GFLAGS_DLL_DECLARE_FLAG
#endif
#define STRIP_FLAG_HELP 1 #define STRIP_FLAG_HELP 1
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <osquery/core/core.h> #include <osquery/core/core.h>
#include <osquery/utils/status/status.h> #include <osquery/utils/status/status.h>
#ifdef FREEBSD
#define GFLAGS_NAMESPACE gflags
#elif !defined(GFLAGS_NAMESPACE)
#define GFLAGS_NAMESPACE google
#endif
namespace osquery { namespace osquery {
struct FlagDetail { struct FlagDetail {