Commit 492ac156 authored by Andreas Schuh's avatar Andreas Schuh

Fix DLL build on Windows and use PathMatchSpec instead of fnmatch.

Expose as few system variables as possible through public interface.
Perform STRIP_FLAGS_HELP test using CMake instead of Bash.
Change file path separator used by gflags_reporting.cc to backslash on Windwos.
parent cf92ec3b
cmake_minimum_required(VERSION 2.8.4 FATAL_ERROR)
if (WIN32 AND NOT CYGWIN)
set (WINDOWS 1)
else ()
set (WINDOWS 0)
endif ()
# ----------------------------------------------------------------------------
# includes
set (CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
......@@ -27,7 +33,12 @@ version_numbers (
# ----------------------------------------------------------------------------
# configure options
option (BUILD_SHARED_LIBS "Request build of shared libraries." OFF)
set (GFLAGS_SHARED_LIBS ${BUILD_SHARED_LIBS})
if (WINDOWS AND BUILD_SHARED_LIBS)
set (GFLAGS_IS_A_DLL 1)
else ()
set (GFLAGS_IS_A_DLL 0)
endif ()
option (BUILD_gflags_LIB "Request build of the multi-threaded gflags library." ON)
option (BUILD_gflags_nothreads_LIB "Request build of the single-threaded gflags library." ON)
......@@ -91,18 +102,44 @@ if (NOT GFLAGS_INTTYPES_FORMAT)
" Set GFLAGS_INTTYPES_FORMAT to either C99, BSD, or VC7 and try again.")
endif ()
endif ()
set ("GFLAGS_INTTYPES_FORMAT_${GFLAGS_INTTYPES_FORMAT}" TRUE)
# use of special characters in strings to circumvent bug #0008226
if ("^${GFLAGS_INTTYPES_FORMAT}$" STREQUAL "^WIN$")
set_property (CACHE GFLAGS_INTTYPES_FORMAT PROPERTY VALUE VC7)
endif ()
if (NOT GFLAGS_INTTYPES_FORMAT MATCHES "^(C99|BSD|VC7)$")
message (FATAL_ERROR "Invalid value for GFLAGS_INTTYPES_FORMAT! Choose one of \"C99\", \"BSD\", or \"VC7\"")
endif ()
set (GFLAGS_INTTYPES_FORMAT_C99 0)
set (GFLAGS_INTTYPES_FORMAT_BSD 0)
set (GFLAGS_INTTYPES_FORMAT_VC7 0)
set ("GFLAGS_INTTYPES_FORMAT_${GFLAGS_INTTYPES_FORMAT}" 1)
foreach (fname IN ITEMS stdint sys/types fnmatch inttypes unistd sys/stat)
string (TOUPPER "${fname}" FNAME)
string (REGEX REPLACE "/" "_" FNAME "${FNAME}")
check_include_file_cxx ("${fname}.h" GFLAGS_HAVE_${FNAME}_H)
if (HAVE_${FNAME}_H)
# set by check_type_size already
set (GFLAGS_HAVE_${FNAME}_H ${HAVE_${FNAME}_H})
else ()
check_include_file_cxx ("${fname}.h" GFLAGS_HAVE_${FNAME}_H)
endif ()
endforeach ()
if (NOT GFLAGS_HAVE_FNMATCH_H AND WINDOWS)
check_include_file_cxx ("shlwapi.h" GFLAGS_HAVE_SHLWAPI_H)
endif ()
bool_to_int(GFLAGS_HAVE_STDINT_H)
bool_to_int(GFLAGS_HAVE_SYS_TYPES_H)
bool_to_int(GFLAGS_HAVE_INTTYPES_H)
foreach (fname IN ITEMS strtoll strtoq)
string (TOUPPER "${fname}" FNAME)
check_cxx_symbol_exists ("${fname}" stdlib.h GFLAGS_HAVE_${FNAME})
endforeach ()
if (MSVC)
set (GFLAGS_HAVE_strtoll FALSE)
set (GFLAGS_HAVE_strtoq FALSE)
else ()
foreach (fname IN ITEMS strtoll strtoq)
string (TOUPPER "${fname}" FNAME)
check_cxx_symbol_exists ("${fname}" stdlib.h GFLAGS_HAVE_${FNAME})
endforeach ()
endif ()
set (CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package (ThreadsCXX)
......@@ -137,7 +174,7 @@ set (GFLAGS_SRCS
"gflags_completions.cc"
)
if (WIN32)
if (WINDOWS)
list (APPEND PRIVATE_HDRS "windows_port.h")
list (APPEND GFLAGS_SRCS "windows_port.cc")
endif ()
......@@ -169,18 +206,11 @@ include_directories ("${PROJECT_BINARY_DIR}/include/${GFLAGS_NAMESPACE}")
set (LIB_TARGETS)
if (BUILD_gflags_LIB)
add_library (gflags ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
if (WIN32 AND BUILD_SHARED_LIBS)
set_target_properties (gflags PROPERTIES COMPILE_DEFINITIONS GFLAGS_DLL_EXPORT)
endif ()
list (APPEND LIB_TARGETS gflags)
endif ()
if (BUILD_gflags_nothreads_LIB)
add_library (gflags_nothreads ${GFLAGS_SRCS} ${PRIVATE_HDRS} ${PUBLIC_HDRS})
if (WIN32 AND BUILD_SHARED_LIBS)
set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS "GFLAGS_DLL_EXPORT;NO_THREADS")
else ()
set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS NO_THREADS)
endif ()
set_target_properties (gflags_nothreads PROPERTIES COMPILE_DEFINITIONS NO_THREADS)
list (APPEND LIB_TARGETS gflags_nothreads)
endif ()
......
## Utility CMake functions.
# ----------------------------------------------------------------------------
## Convert boolean value to 0 or 1
macro (bool_to_int VAR)
if (${VAR})
set (${VAR} 1)
else ()
set (${VAR} 0)
endif ()
endmacro ()
# ----------------------------------------------------------------------------
## Extract version numbers from version string.
function (version_numbers version major minor patch)
......
......@@ -2,10 +2,86 @@
// Note: This header file is only used internally. It is not part of public interface!
#include "gflags_declare.h" // system checks
// Whether gflags library is shared. Used for DLL import declaration.
#define GFLAGS_IS_A_DLL @GFLAGS_IS_A_DLL@
// ---------------------------------------------------------------------------
// Additional meta-information
// System checks
// Define if you have the <stdint.h> header file.
#cmakedefine GFLAGS_HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#cmakedefine GFLAGS_HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
#cmakedefine GFLAGS_HAVE_INTTYPES_H
// Define if you have the <sys/stat.h> header file.
#cmakedefine GFLAGS_HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
#cmakedefine GFLAGS_HAVE_UNISTD_H
// Define if you have the <fnmatch.h> header file.
#cmakedefine GFLAGS_HAVE_FNMATCH_H
// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
#cmakedefine GFLAGS_HAVE_SHLWAPI_H
// Define if you have the strtoll function.
#cmakedefine GFLAGS_HAVE_STRTOLL
// Define if you have the strtoq function.
#cmakedefine GFLAGS_HAVE_STRTOQ
// Define if you have the <pthread.h> header file.
#cmakedefine GFLAGS_HAVE_PTHREAD
// Define if your pthread library defines the type pthread_rwlock_t
#cmakedefine GFLAGS_HAVE_RWLOCK
// Backwards compatibility in case users defined these macros themselves
// or allow users to use these more general macros if the gflags library
// is build as part of a user project, e.g., included as Git submodule
#if defined(HAVE_STDINT_H) && !defined(GFLAGS_HAVE_STDINT_H)
# define GFLAGS_HAVE_STDINT_H
#endif
#if defined(HAVE_SYS_TYPES_H) && !defined(GFLAGS_HAVE_SYS_TYPES_H)
# define GFLAGS_HAVE_SYS_TYPES_H
#endif
#if defined(HAVE_INTTYPES_H) && !defined(GFLAGS_HAVE_INTTYPES_H)
# define GFLAGS_HAVE_INTTYPES_H
#endif
#if defined(HAVE_SYS_STAT_H) && !defined(GFLAGS_HAVE_SYS_STAT_H)
# define GFLAGS_HAVE_SYS_STAT_H
#endif
#if defined(HAVE_UNISTD_H) && !defined(GFLAGS_HAVE_UNISTD_H)
# define GFLAGS_HAVE_UNISTD_H
#endif
#if defined(HAVE_FNMATCH_H) && !defined(GFLAGS_HAVE_FNMATCH_H)
# define GFLAGS_HAVE_FNMATCH_H
#endif
#if defined(HAVE_STRTOLL) && !defined(GFLAGS_HAVE_STRTOLL)
# define GFLAGS_HAVE_STRTOLL
#endif
#if defined(HAVE_STRTOLQ) && !defined(GFLAGS_HAVE_STRTOLQ)
# define GFLAGS_HAVE_STRTOLQ
#endif
#if defined(HAVE_PTHREAD) && !defined(GFLAGS_HAVE_PTHREAD)
# define GFLAGS_HAVE_PTHREAD
#endif
#if defined(HAVE_RWLOCK) && !defined(GFLAGS_HAVE_RWLOCK)
# define GFLAGS_HAVE_RWLOCK
#endif
// gcc requires this to get PRId64, etc.
#if defined(GFLAGS_HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1
#endif
// ---------------------------------------------------------------------------
// Package information
// Name of package.
#define PACKAGE @PROJECT_NAME@
......@@ -30,10 +106,42 @@
// ---------------------------------------------------------------------------
// Path separator
#define PATH_SEPARATOR '/'
#ifndef PATH_SEPARATOR
# if _WIN32
# define PATH_SEPARATOR '\\'
# else
# define PATH_SEPARATOR '/'
# endif
#endif
// ---------------------------------------------------------------------------
// Windows port
// Windows
// Always export symbols when compiling a shared library as this file is only
// included by internal modules when building the gflags library itself.
// The gflags_declare.h header file will set it to import these symbols otherwise.
#ifndef GFLAGS_DLL_DECL
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllexport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// Flags defined by the gflags library itself must be exported
#ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
#endif
#ifdef _WIN32
// The unittests import the symbols of the shared gflags library
# if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
# endif
# include "windows_port.h"
#endif
// Export of STL class instantiations -- no extern keyword to not trigger a warning
// \sa http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958
#if GFLAGS_IS_A_DLL && defined(_MSC_VER) && _MSC_VER >= 1100
# define GFLAGS_EXTERN_STL
#endif
\ No newline at end of file
......@@ -93,8 +93,11 @@
#include <assert.h>
#include <ctype.h>
#include <errno.h>
#ifdef GFLAGS_HAVE_FNMATCH_H
#if defined(GFLAGS_HAVE_FNMATCH_H)
# include <fnmatch.h>
#elif defined(GFLAGS_HAVE_SHLWAPI_H)
# include <shlwapi.h>
# pragma comment(lib, "shlwapi.lib")
#endif
#include <stdarg.h> // For va_list and related operations
#include <stdio.h>
......@@ -109,12 +112,6 @@
#include "mutex.h"
#include "util.h"
// Export the following flags only if the gflags library is a DLL
#ifndef GFLAGS_SHARED_LIBS
# undef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG
#endif
// Special flags, type 1: the 'recursive' flags. They set another flag's val.
DEFINE_string(flagfile, "", "load flags from file");
DEFINE_string(fromenv, "", "set flags from the environment"
......@@ -1310,13 +1307,12 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
// We try matching both against the full argv0 and basename(argv0)
if (glob == ProgramInvocationName() // small optimization
|| glob == ProgramInvocationShortName()
#ifdef GFLAGS_HAVE_FNMATCH_H
|| fnmatch(glob.c_str(),
ProgramInvocationName(),
FNM_PATHNAME) == 0
|| fnmatch(glob.c_str(),
ProgramInvocationShortName(),
FNM_PATHNAME) == 0
#if defined(GFLAGS_HAVE_FNMATCH_H)
|| fnmatch(glob.c_str(), ProgramInvocationName(), FNM_PATHNAME) == 0
|| fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0
#elif defined(GFLAGS_HAVE_SHLWAPI_H)
|| PathMatchSpec(glob.c_str(), ProgramInvocationName())
|| PathMatchSpec(glob.c_str(), ProgramInvocationShortName())
#endif
) {
flags_are_relevant = true;
......
......@@ -84,11 +84,13 @@
#include "gflags_declare.h" // IWYU pragma: export
// Export/import STL instantiations used as data members of exported classes
// \sa http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958
#ifdef GFLAGS_EXTERN_STL
GFLAGS_EXTERN_STL template class GFLAGS_DLL_DECL std::allocator<char>;
GFLAGS_EXTERN_STL template class GFLAGS_DLL_DECL std::basic_string<char>;
// We always want to export variables defined in user code
#ifndef GFLAGS_DLL_DEFINE_FLAG
# ifdef _MSC_VER
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
......@@ -124,19 +126,12 @@ namespace GFLAGS_NAMESPACE {
// 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 bool RegisterFlagValidator(const bool* flag,
bool (*validate_fn)(const char*, bool));
extern bool RegisterFlagValidator(const int32* flag,
bool (*validate_fn)(const char*, int32));
extern bool RegisterFlagValidator(const int64* flag,
bool (*validate_fn)(const char*, int64));
extern bool RegisterFlagValidator(const uint64* flag,
bool (*validate_fn)(const char*, uint64));
extern bool RegisterFlagValidator(const double* flag,
bool (*validate_fn)(const char*, double));
extern bool RegisterFlagValidator(const std::string* flag,
bool (*validate_fn)(const char*,
const std::string&));
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 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) \
......@@ -154,7 +149,12 @@ extern bool RegisterFlagValidator(const std::string* flag,
// 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.
#ifdef _MSC_VER
# pragma warning(push)
// The solution offered at http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958
// is not really desireable as we don't want to explicitly instantiate/export any STL types
# pragma warning(disable: 4251)
#endif
struct GFLAGS_DLL_DECL CommandLineFlagInfo {
std::string name; // the name of the flag
std::string type; // the type of the flag: int32, etc
......@@ -162,46 +162,49 @@ struct GFLAGS_DLL_DECL CommandLineFlagInfo {
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)
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)
};
#ifdef _MSC_VER
# pragma warning(pop)
#endif
// 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 void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
// These two are actually defined in gflags_reporting.cc.
extern void ShowUsageWithFlags(const char *argv0); // what --help does
extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
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 std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
// Thread-hostile; meant to be called before any threads are spawned.
extern void SetArgv(int argc, const char** argv);
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 const std::vector<std::string>& GetArgvs();
extern const char* GetArgv(); // all of argv as a string
extern const char* GetArgv0(); // only argv0
extern uint32 GetArgvSum(); // simple checksum of argv
extern const char* ProgramInvocationName(); // argv0, or "UNKNOWN" if not set
extern const char* ProgramInvocationShortName(); // basename(argv0)
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 const char* ProgramUsage(); // string set by SetUsageMessage()
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 const char* VersionString(); // string set by SetVersionString()
extern GFLAGS_DLL_DECL const char* VersionString(); // string set by SetVersionString()
......@@ -215,17 +218,16 @@ extern const char* VersionString(); // string set by SetVersionString()
// Return true iff the flagname was found.
// OUTPUT is set to the flag's value, or unchanged if we return false.
extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
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 bool GetCommandLineFlagInfo(const char* name,
CommandLineFlagInfo* OUTPUT);
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 CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
enum GFLAGS_DLL_DECL FlagSettingMode {
// update the flag's value (can call this multiple times).
......@@ -247,9 +249,8 @@ enum GFLAGS_DLL_DECL FlagSettingMode {
// non-empty else.
// SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
extern std::string SetCommandLineOption(const char* name, const char* value);
extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
FlagSettingMode set_mode);
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);
// --------------------------------------------------------------------
......@@ -297,17 +298,17 @@ GFLAGS_ATTRIBUTE_UNUSED;
// Some deprecated or hopefully-soon-to-be-deprecated functions.
// This is often used for logging. TODO(csilvers): figure out a better way
extern std::string CommandlineFlagsIntoString();
extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
// Usually where this is used, a FlagSaver should be used instead.
extern bool ReadFlagsFromString(const std::string& flagfilecontents,
const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
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 bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
bool errors_are_fatal); // uses SET_FLAGS_VALUE
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
// --------------------------------------------------------------------
......@@ -318,12 +319,12 @@ extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name
// 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 bool BoolFromEnv(const char *varname, bool defval);
extern int32 Int32FromEnv(const char *varname, int32 defval);
extern int64 Int64FromEnv(const char *varname, int64 defval);
extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
extern double DoubleFromEnv(const char *varname, double defval);
extern const char *StringFromEnv(const char *varname, const char *defval);
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 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);
// --------------------------------------------------------------------
......@@ -335,12 +336,12 @@ extern const char *StringFromEnv(const char *varname, const char *defval);
// 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 void SetUsageMessage(const std::string& usage);
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 void SetVersionString(const std::string& version);
extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
// Looks for flags in argv and parses them. Rearranges argv to put
......@@ -350,7 +351,7 @@ extern void SetVersionString(const std::string& version);
// of the first non-flag argument.
// See top-of-file for more details on this function.
#ifndef SWIG // In swig, use ParseCommandLineFlagsScript() instead.
extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
#endif
......@@ -364,18 +365,18 @@ extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
// 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 uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
bool remove_flags);
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 void HandleCommandLineHelpFlags(); // in gflags_reporting.cc
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 void AllowCommandLineReparsing();
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
......@@ -383,7 +384,7 @@ extern void AllowCommandLineReparsing();
// 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 void ReparseCommandLineNonHelpFlags();
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
......@@ -394,7 +395,7 @@ extern void ReparseCommandLineNonHelpFlags();
// called will have unexpected consequences. This is not safe to run
// when multiple threads might be running: the function is
// thread-hostile.
extern void ShutDownCommandLineFlags();
extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
// --------------------------------------------------------------------
......@@ -425,7 +426,7 @@ extern void ShutDownCommandLineFlags();
// 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 bool FLAGS_whatever;"
// 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.
......@@ -446,7 +447,7 @@ class GFLAGS_DLL_DECL FlagRegisterer {
// binary file. This can reduce the size of the resulting binary
// somewhat, and may also be useful for security reasons.
extern const char kStrippedFlagHelp[];
extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
} // namespace GFLAGS_NAMESPACE
......@@ -561,7 +562,7 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
clstring* const FLAGS_no##name = ::fLS:: \
dont_pass0toDEFINE_string(s_##name[0].s, \
val); \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
static GFLAGS_NAMESPACE::FlagRegisterer o_##name( \
#name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__, \
s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name)); \
extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name; \
......
......@@ -47,9 +47,6 @@
#define GFLAGS_VERSION_MINOR @PACKAGE_VERSION_MINOR@ ///< Minor version number.
#define GFLAGS_VERSION_PATCH @PACKAGE_VERSION_PATCH@ ///< Version patch number.
// Whether gflags library is shared. Used for DLL import declaration.
#cmakedefine GFLAGS_SHARED_LIBS
// ---------------------------------------------------------------------------
// Namespace for gflags symbols.
#define GFLAGS_NAMESPACE @GFLAGS_NAMESPACE@
......@@ -60,148 +57,49 @@
// ---------------------------------------------------------------------------
// Windows DLL import/export.
// We always want to import the symbols of the gflags library
#ifndef GFLAGS_DLL_DECL
# if defined(_MSC_VER) && defined(GFLAGS_SHARED_LIBS)
# ifdef GFLAGS_DLL_EXPORT
# define GFLAGS_DLL_DECL __declspec(dllexport)
# else
# define GFLAGS_DLL_DECL __declspec(dllimport)
# endif
# if @GFLAGS_IS_A_DLL@ && defined(_MSC_VER)
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL
# endif
#endif
// By default, we always want to export defined variables, assuming
// that the DEFINE_FLAG macros are used within shared modules.
#ifndef GFLAGS_DLL_DEFINE_FLAG
# if defined(_MSC_VER)
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# else
# define GFLAGS_DLL_DEFINE_FLAG
# endif
#endif
// By default, we always want to export defined variables, assuming
// that the DECLARE_FLAG macros are used within shared modules.
// We always want to import variables declared in user code
#ifndef GFLAGS_DLL_DECLARE_FLAG
# if defined(_MSC_VER)
# ifdef _MSC_VER
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# else
# define GFLAGS_DLL_DECLARE_FLAG
# endif
#endif
// Export/import of STL class instantiations
// \sa http://support.microsoft.com/default.aspx?scid=KB;EN-US;168958
#if defined(GFLAGS_SHARED_LIBS) && defined(_MSC_VER) && _MSC_VER >= 1100
# ifdef GFLAGS_DLL_EXPORT
# define GFLAGS_EXTERN_STL
# else
# define GFLAGS_EXTERN_STL extern
# endif
#endif
// ---------------------------------------------------------------------------
// Available system headers
// Define if you have the <stdint.h> header file.
#cmakedefine GFLAGS_HAVE_STDINT_H
// Define if you have the <sys/types.h> header file.
#cmakedefine GFLAGS_HAVE_SYS_TYPES_H
// Define if you have the <inttypes.h> header file.
#cmakedefine GFLAGS_HAVE_INTTYPES_H
// Define if you have the <sys/stat.h> header file.
#cmakedefine GFLAGS_HAVE_SYS_STAT_H
// Define if you have the <unistd.h> header file.
#cmakedefine GFLAGS_HAVE_UNISTD_H
// Define if you have the <fnmatch.h> header file.
#cmakedefine GFLAGS_HAVE_FNMATCH_H
// Define if you have the strtoll function.
#cmakedefine GFLAGS_HAVE_STRTOLL
// Define if you have the strtoq function.
#cmakedefine GFLAGS_HAVE_STRTOQ
// Define if you have the <pthread.h> header file.
#cmakedefine GFLAGS_HAVE_PTHREAD
// Define if your pthread library defines the type pthread_rwlock_t
#cmakedefine GFLAGS_HAVE_RWLOCK
// Backwards compatibility in case users defined these macros themselves
// or allow users to use these more general macros if the gflags library
// is build as part of a user project, e.g., included as Git submodule
#if defined(HAVE_STDINT_H) && !defined(GFLAGS_HAVE_STDINT_H)
# define GFLAGS_HAVE_STDINT_H
#endif
#if defined(HAVE_SYS_TYPES_H) && !defined(GFLAGS_HAVE_SYS_TYPES_H)
# define GFLAGS_HAVE_SYS_TYPES_H
#endif
#if defined(HAVE_INTTYPES_H) && !defined(GFLAGS_HAVE_INTTYPES_H)
# define GFLAGS_HAVE_INTTYPES_H
#endif
#if defined(HAVE_SYS_STAT_H) && !defined(GFLAGS_HAVE_SYS_STAT_H)
# define GFLAGS_HAVE_SYS_STAT_H
#endif
#if defined(HAVE_UNISTD_H) && !defined(GFLAGS_HAVE_UNISTD_H)
# define GFLAGS_HAVE_UNISTD_H
#endif
#if defined(HAVE_FNMATCH_H) && !defined(GFLAGS_HAVE_FNMATCH_H)
# define GFLAGS_HAVE_FNMATCH_H
#endif
#if defined(HAVE_STRTOLL) && !defined(GFLAGS_HAVE_STRTOLL)
# define GFLAGS_HAVE_STRTOLL
#endif
#if defined(HAVE_STRTOLQ) && !defined(GFLAGS_HAVE_STRTOLQ)
# define GFLAGS_HAVE_STRTOLQ
#endif
#if defined(HAVE_PTHREAD) && !defined(GFLAGS_HAVE_PTHREAD)
# define GFLAGS_HAVE_PTHREAD
#endif
#if defined(HAVE_RWLOCK) && !defined(GFLAGS_HAVE_RWLOCK)
# define GFLAGS_HAVE_RWLOCK
#endif
// gcc requires this to get PRId64, etc.
#if defined(GFLAGS_HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
# define __STDC_FORMAT_MACROS 1
#endif
// ---------------------------------------------------------------------------
// Flag types
#include <string>
#if defined(GFLAGS_HAVE_STDINT_H)
#if @GFLAGS_HAVE_STDINT_H@
# include <stdint.h> // the normal place uint32_t is defined
#elif defined(GFLAGS_HAVE_SYS_TYPES_H)
#elif @GFLAGS_HAVE_SYS_TYPES_H@
# include <sys/types.h> // the normal place u_int32_t is defined
#elif defined(GFLAGS_HAVE_INTTYPES_H)
#elif @GFLAGS_HAVE_INTTYPES_H@
# include <inttypes.h> // a third place for uint32_t or u_int32_t
#endif
#cmakedefine GFLAGS_INTTYPES_FORMAT_C99
#cmakedefine GFLAGS_INTTYPES_FORMAT_BSD
#cmakedefine GFLAGS_INTTYPES_FORMAT_VC7
namespace GFLAGS_NAMESPACE {
#if defined(GFLAGS_INTTYPES_FORMAT_C99)
#if @GFLAGS_INTTYPES_FORMAT_C99@ // C99
typedef int32_t int32;
typedef uint32_t uint32;
typedef int64_t int64;
typedef uint64_t uint64;
#elif defined(GFLAGS_INTTYPES_FORMAT_BSD)
#elif @GFLAGS_INTTYPES_FORMAT_BSD@ // BSD
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif defined(GFLAGS_INTTYPES_FORMAT_VC7) // Windows
#elif @GFLAGS_INTTYPES_FORMAT_VC7@ // Windows
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
......
......@@ -246,7 +246,7 @@ static bool FileMatchesSubstring(const string& filename,
// the string to be at the beginning of a directory component.
// That should match the first directory component as well, so
// we allow '/foo' to match a filename of 'foo'.
if (!target->empty() && (*target)[0] == '/' &&
if (!target->empty() && (*target)[0] == PATH_SEPARATOR &&
strncmp(filename.c_str(), target->c_str() + 1,
strlen(target->c_str() + 1)) == 0)
return true;
......@@ -352,7 +352,8 @@ static void ShowVersion() {
static void AppendPrognameStrings(vector<string>* substrings,
const char* progname) {
string r("/");
string r("");
r += PATH_SEPARATOR;
r += progname;
substrings->push_back(r + ".");
substrings->push_back(r + "-main.");
......@@ -387,7 +388,7 @@ void HandleCommandLineHelpFlags() {
gflags_exitfunc(1);
} else if (!FLAGS_helpon.empty()) {
string restrict = "/" + FLAGS_helpon + ".";
string restrict = PATH_SEPARATOR + FLAGS_helpon + ".";
ShowUsageWithFlagsRestrict(progname, restrict.c_str());
gflags_exitfunc(1);
......@@ -409,7 +410,7 @@ void HandleCommandLineHelpFlags() {
++flag) {
if (!FileMatchesSubstring(flag->filename, substrings))
continue;
const string package = Dirname(flag->filename) + "/";
const string package = Dirname(flag->filename) + PATH_SEPARATOR;
if (package != last_package) {
ShowUsageWithFlagsRestrict(progname, package.c_str());
VLOG(7) << "Found package: " << package;
......
......@@ -2,9 +2,9 @@
# ----------------------------------------------------------------------------
# output directories
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/bin")
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/lib")
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/Testing/lib")
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
set (CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
set (CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib")
# set working directory of test commands
set (GFLAGS_FLAGFILES_DIR "${CMAKE_CURRENT_SOURCE_DIR}")
......@@ -15,139 +15,134 @@ include_directories ("${CMAKE_CURRENT_SOURCE_DIR}")
link_libraries (gflags_nothreads)
# ----------------------------------------------------------------------------
# STRIP_FLAG_HELP: check with "strings" that help text is not in binary
if (UNIX AND NOT CYGWIN)
add_executable (strip_flags gflags_strip_flags_test.cc)
add_test (
NAME strip_flags
COMMAND /bin/bash "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.sh"
"${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/strip_flags"
)
endif ()
# STRIP_FLAG_HELP
add_executable (gflags_strip_flags_test gflags_strip_flags_test.cc)
# Make sure the --help output doesn't print the stripped text.
add_gflags_test (strip_flags_help 1 "" "This text should be stripped out" gflags_strip_flags_test --help)
# Make sure the stripped text isn't in the binary at all.
add_test (
NAME strip_flags_binary
COMMAND "${CMAKE_COMMAND}" "-DBINARY=$<TARGET_FILE:gflags_strip_flags_test>"
-P "${CMAKE_CURRENT_SOURCE_DIR}/gflags_strip_flags_test.cmake"
)
# ----------------------------------------------------------------------------
# unit tests
configure_file (gflags_unittest.cc gflags_unittest-main.cc COPYONLY)
configure_file (gflags_unittest.cc gflags_unittest_main.cc COPYONLY)
add_executable (unittest gflags_unittest.cc)
add_executable (unittest2 gflags_unittest-main.cc)
add_executable (unittest3 gflags_unittest_main.cc)
add_executable (gflags_unittest gflags_unittest.cc)
add_executable (gflags_unittest-main gflags_unittest-main.cc)
add_executable (gflags_unittest_main gflags_unittest_main.cc)
if (UNIX)
set (SLASH "/")
else ()
if (WIN32 AND NOT CYGWIN)
set (SLASH "\\\\")
else ()
set (SLASH "/")
endif ()
# First, just make sure the unittest works as-is
add_gflags_test(unittest 0 "" "" unittest)
# First, just make sure the gflags_unittest works as-is
add_gflags_test(unittest 0 "" "" gflags_unittest)
# --help should show all flags, including flags from gflags_reporting
add_gflags_test(help-reporting 1 "${SLASH}gflags_reporting.cc" "" unittest --help)
add_gflags_test(help-reporting 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --help)
# Make sure that --help prints even very long helpstrings.
add_gflags_test(long-helpstring 1 "end of a long helpstring" "" unittest --help)
add_gflags_test(long-helpstring 1 "end of a long helpstring" "" gflags_unittest --help)
# Make sure --help reflects flag changes made before flag-parsing
add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" "" unittest --help)
add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" "" unittest --help)
add_gflags_test(changed_bool1 1 "-changed_bool1 (changed) type: bool default: true" "" gflags_unittest --help)
add_gflags_test(changed_bool2 1 "-changed_bool2 (changed) type: bool default: false currently: true" "" gflags_unittest --help)
# And on the command-line, too
add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" "" unittest --changeable_string_var 2 --help)
add_gflags_test(changeable_string_var 1 "-changeable_string_var () type: string default: \"1\" currently: \"2\"" "" gflags_unittest --changeable_string_var 2 --help)
# --nohelp and --help=false should be as if we didn't say anything
add_gflags_test(nohelp 0 "PASS" "" unittest --nohelp)
add_gflags_test(help=false 0 "PASS" "" unittest --help=false)
add_gflags_test(nohelp 0 "PASS" "" gflags_unittest --nohelp)
add_gflags_test(help=false 0 "PASS" "" gflags_unittest --help=false)
# --helpfull is the same as help
add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc" "" unittest --helpfull)
add_gflags_test(helpfull 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helpfull)
# --helpshort should show only flags from the unittest itself
add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags_reporting.cc" unittest --helpshort)
# --helpshort should show only flags from the gflags_unittest itself
add_gflags_test(helpshort 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest --helpshort)
# --helpshort should show the tldflag we created in the unittest dir
add_gflags_test(helpshort-tldflag1 1 "tldflag1" "${SLASH}google.cc" unittest --helpshort)
add_gflags_test(helpshort-tldflag2 1 "tldflag2" "${SLASH}google.cc" unittest --helpshort)
# --helpshort should show the tldflag we created in the gflags_unittest dir
add_gflags_test(helpshort-tldflag1 1 "tldflag1" "${SLASH}google.cc:" gflags_unittest --helpshort)
add_gflags_test(helpshort-tldflag2 1 "tldflag2" "${SLASH}google.cc:" gflags_unittest --helpshort)
# --helpshort should work if the main source file is suffixed with [_-]main
add_gflags_test(helpshort-main 1 "${SLASH}gflags_unittest-main.cc" "${SLASH}gflags_reporting.cc" unittest2 --helpshort)
add_gflags_test(helpshort_main 1 "${SLASH}gflags_unittest_main.cc" "${SLASH}gflags_reporting.cc" unittest3 --helpshort)
add_gflags_test(helpshort-main 1 "${SLASH}gflags_unittest-main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest-main --helpshort)
add_gflags_test(helpshort_main 1 "${SLASH}gflags_unittest_main.cc:" "${SLASH}gflags_reporting.cc:" gflags_unittest_main --helpshort)
# --helpon needs an argument
add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" "" unittest --helpon)
if (BUILD_SHARED_LIBS)
# --helpon argument indicates what file we'll show args from
# TODO(andreas): This test fails. Why is there no help for the gflags module ?
add_gflags_test(helpon=gflags 1 "${SLASH}gflags.cc" "${SLASH}gflags_unittest.cc" unittest --helpon=gflags)
# another way of specifying the argument
# TODO(andreas): This test fails. Why is there no help for the gflags module ?
add_gflags_test(helpon_gflags 1 "${SLASH}gflags.cc" "${SLASH}gflags_unittest.cc" unittest --helpon gflags)
endif ()
add_gflags_test(helpon 1 "'--helpon' is missing its argument; flag description: show help on" "" gflags_unittest --helpon)
# --helpon argument indicates what file we'll show args from
add_gflags_test(helpon=gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpon=gflags)
# another way of specifying the argument
add_gflags_test(helpon_gflags 1 "${SLASH}gflags.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpon gflags)
# test another argument
add_gflags_test(helpon=gflags_unittest 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags.cc" unittest --helpon=gflags_unittest)
add_gflags_test(helpon=gflags_unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:" gflags_unittest --helpon=gflags_unittest)
# helpmatch is like helpon but takes substrings
add_gflags_test(helpmatch_reporting 1 "${SLASH}gflags_reporting.cc" "${SLASH}gflags_unittest.cc" unittest -helpmatch reporting)
add_gflags_test(helpmatch=unittest 1 "${SLASH}gflags_unittest.cc" "${SLASH}gflags.cc:" unittest -helpmatch=unittest)
add_gflags_test(helpmatch_reporting 1 "${SLASH}gflags_reporting.cc:" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpmatch reporting)
add_gflags_test(helpmatch=unittest 1 "${SLASH}gflags_unittest.cc:" "${SLASH}gflags.cc:" gflags_unittest -helpmatch=unittest)
# if no flags are found with helpmatch or helpon, suggest --help
add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "${SLASH}gflags_unittest.cc" unittest -helpmatch=nosuchsubstring)
add_gflags_test(helpon=nosuchmodule 1 "No modules matched" "${SLASH}gflags_unittest.cc" unittest -helpon=nosuchmodule)
add_gflags_test(helpmatch=nosuchsubstring 1 "No modules matched" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpmatch=nosuchsubstring)
add_gflags_test(helpon=nosuchmodule 1 "No modules matched" "${SLASH}gflags_unittest.cc:" gflags_unittest -helpon=nosuchmodule)
# helppackage shows all the flags in the same dir as this unittest
# --help should show all flags, including flags from google.cc
add_gflags_test(helppackage 1 "${SLASH}gflags_reporting.cc" "" unittest --helppackage)
add_gflags_test(helppackage 1 "${SLASH}gflags_reporting.cc:" "" gflags_unittest --helppackage)
# xml!
add_gflags_test(helpxml 1 "${SLASH}gflags_unittest.cc</file>" "${SLASH}gflags_unittest.cc:" unittest --helpxml)
add_gflags_test(helpxml 1 "${SLASH}gflags_unittest.cc</file>" "${SLASH}gflags_unittest.cc:" gflags_unittest --helpxml)
# just print the version info and exit
add_gflags_test(version-1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --version)
add_gflags_test(version-2 0 "version test_version" "${SLASH}gflags_unittest.cc" unittest --version)
add_gflags_test(version-1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --version)
add_gflags_test(version-2 0 "version test_version" "${SLASH}gflags_unittest.cc:" gflags_unittest --version)
# --undefok is a fun flag...
add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" "" unittest --undefok= --foo --unused_bool)
add_gflags_test(undefok-2 0 "PASS" "" unittest --undefok=foo --foo --unused_bool)
add_gflags_test(undefok-1 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok= --foo --unused_bool)
add_gflags_test(undefok-2 0 "PASS" "" gflags_unittest --undefok=foo --foo --unused_bool)
# If you say foo is ok to be undefined, we'll accept --nofoo as well
add_gflags_test(undefok-3 0 "PASS" "" unittest --undefok=foo --nofoo --unused_bool)
add_gflags_test(undefok-3 0 "PASS" "" gflags_unittest --undefok=foo --nofoo --unused_bool)
# It's ok if the foo is in the middle
add_gflags_test(undefok-4 0 "PASS" "" unittest --undefok=fee,fi,foo,fum --foo --unused_bool)
add_gflags_test(undefok-4 0 "PASS" "" gflags_unittest --undefok=fee,fi,foo,fum --foo --unused_bool)
# But the spelling has to be just right...
add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" "" unittest --undefok=fo --foo --unused_bool)
add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" "" unittest --undefok=foot --foo --unused_bool)
add_gflags_test(undefok-5 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok=fo --foo --unused_bool)
add_gflags_test(undefok-6 1 "unknown command line flag 'foo'" "" gflags_unittest --undefok=foot --foo --unused_bool)
# See if we can successfully load our flags from the flagfile
add_gflags_test(flagfile.1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest "--flagfile=flagfile.1")
add_gflags_test(flagfile.2 0 "PASS" "" unittest "--flagfile=flagfile.2")
add_gflags_test(flagfile.3 0 "PASS" "" unittest "--flagfile=flagfile.3")
add_gflags_test(flagfile.1 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest "--flagfile=flagfile.1")
add_gflags_test(flagfile.2 0 "PASS" "" gflags_unittest "--flagfile=flagfile.2")
add_gflags_test(flagfile.3 0 "PASS" "" gflags_unittest "--flagfile=flagfile.3")
# Also try to load flags from the environment
add_gflags_test(fromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --fromenv=version)
add_gflags_test(tryfromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --tryfromenv=version)
add_gflags_test(fromenv=help 0 "PASS" "" unittest --fromenv=help)
add_gflags_test(tryfromenv=help 0 "PASS" "" unittest --tryfromenv=help)
add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" unittest --fromenv=helpfull)
add_gflags_test(tryfromenv=helpfull 0 "PASS" "" unittest --tryfromenv=helpfull)
add_gflags_test(tryfromenv=undefok 0 "PASS" "" unittest --tryfromenv=undefok --foo)
add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" unittest --tryfromenv=weirdo)
add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --tryfromenv=test_bool,version,unused_bool)
add_gflags_test(fromenv=test_bool 1 "not found in environment" "" unittest --fromenv=test_bool)
add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" "" unittest --fromenv=test_bool,ok)
add_gflags_test(fromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --fromenv=version)
add_gflags_test(tryfromenv=version 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=version)
add_gflags_test(fromenv=help 0 "PASS" "" gflags_unittest --fromenv=help)
add_gflags_test(tryfromenv=help 0 "PASS" "" gflags_unittest --tryfromenv=help)
add_gflags_test(fromenv=helpfull 1 "helpfull not found in environment" "" gflags_unittest --fromenv=helpfull)
add_gflags_test(tryfromenv=helpfull 0 "PASS" "" gflags_unittest --tryfromenv=helpfull)
add_gflags_test(tryfromenv=undefok 0 "PASS" "" gflags_unittest --tryfromenv=undefok --foo)
add_gflags_test(tryfromenv=weirdo 1 "unknown command line flag" "" gflags_unittest --tryfromenv=weirdo)
add_gflags_test(tryfromenv-multiple 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --tryfromenv=test_bool,version,unused_bool)
add_gflags_test(fromenv=test_bool 1 "not found in environment" "" gflags_unittest --fromenv=test_bool)
add_gflags_test(fromenv=test_bool-ok 1 "unknown command line flag" "" gflags_unittest --fromenv=test_bool,ok)
# Here, the --version overrides the fromenv
add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "${SLASH}gflags_unittest.cc" unittest --fromenv=test_bool,version,ok)
add_gflags_test(version-overrides-fromenv 0 "gflags_unittest" "${SLASH}gflags_unittest.cc:" gflags_unittest --fromenv=test_bool,version,ok)
# Make sure -- by itself stops argv processing
add_gflags_test(dashdash 0 "PASS" "" unittest -- --help)
add_gflags_test(dashdash 0 "PASS" "" gflags_unittest -- --help)
# And we should die if the flag value doesn't pass the validator
add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" unittest --always_fail)
add_gflags_test(always_fail 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" gflags_unittest --always_fail)
# And if locking in validators fails
# TODO(andreas): Worked on Windows 7 Release configuration, but causes
# debugger abort() intervention in case of Debug configuration.
#add_gflags_test(deadlock_if_cant_lock 0 "PASS" "" unittest --deadlock_if_cant_lock)
#add_gflags_test(deadlock_if_cant_lock 0 "PASS" "" gflags_unittest --deadlock_if_cant_lock)
# ----------------------------------------------------------------------------
# (negative) compilation tests
......@@ -159,15 +154,15 @@ if (BUILD_NEGATIVE_COMPILATION_TESTS)
endif ()
set (SRCDIR "${CMAKE_CURRENT_SOURCE_DIR}/nc")
configure_file (gflags_nc.py.in "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" @ONLY)
macro (add_nc_test name)
macro (add_gflags_nc_test name)
add_test (
NAME nc_${name}
COMMAND "${PYTHON_EXECUTABLE}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/nc.py" ${name}
)
endmacro ()
add_nc_test (sanity)
add_nc_test (swapped_args)
add_nc_test (int_instead_of_bool)
add_nc_test (bool_in_quotes)
add_nc_test (define_string_with_0)
add_gflags_nc_test (sanity)
add_gflags_nc_test (swapped_args)
add_gflags_nc_test (int_instead_of_bool)
add_gflags_nc_test (bool_in_quotes)
add_gflags_nc_test (define_string_with_0)
endif ()
\ No newline at end of file
......@@ -55,9 +55,25 @@
#include "config.h"
#undef GFLAGS_DLL_DECL
#ifdef GFLAGS_DLL_DECL
# undef GFLAGS_DLL_DECL
#endif
#ifdef GFLAGS_DLL_DEFINE_FLAG
# undef GFLAGS_DLL_DEFINE_FLAG
#endif
#ifdef GFLAGS_DLL_DECLARE_FLAG
# undef GFLAGS_DLL_DECLARE_FLAG
#endif
#ifdef GFLAGS_DLL_DECL_FOR_UNITTESTS
# define GFLAGS_DLL_DECL GFLAGS_DLL_DECL_FOR_UNITTESTS
# define GFLAGS_DLL_DECL GFLAGS_DLL_DECL_FOR_UNITTESTS
#else
# define GFLAGS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
# define GFLAGS_DLL_DECL // if DLL_DECL_FOR_UNITTESTS isn't defined, use ""
#endif
// Import flags defined by gflags.cc
#if GFLAGS_IS_A_DLL && defined(_MSC_VER)
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
#else
# define GFLAGS_DLL_DECLARE_FLAG
#endif
\ No newline at end of file
if (NOT BINARY)
message (FATAl_ERROR "BINARY file to check not specified!")
endif ()
file (STRINGS "${BINARY}" strings REGEX "This text should be stripped out")
if (strings)
message (FATAL_ERROR "Text not stripped from binary like it should be: ${BINARY}")
endif ()
\ No newline at end of file
#!/bin/sh
#
# Copyright (c) 2011, 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: csilvers@google.com (Craig Silverstein)
if [ -z "$1" ]; then
echo "USAGE: $0 <unittest exe>"
exit 1
fi
BINARY="$1"
# Make sure the binary exists...
if ! "$BINARY" >/dev/null 2>/dev/null
then
echo "Cannot run binary $BINARY"
exit 1
fi
# Make sure the --help output doesn't print the stripped text.
if "$BINARY" --help | grep "This text should be stripped out" >/dev/null 2>&1
then
echo "Text not stripped from --help like it should be: $BINARY"
exit 1
fi
# Make sure the stripped text isn't in the binary at all.
if strings --help >/dev/null 2>&1 # make sure the binary exists
then
# Unfortunately, for us, libtool can replace executables with a
# shell script that does some work before calling the 'real'
# executable under a different name. We need the 'real'
# executable name to run 'strings' on it, so we construct this
# binary to print the real name (argv[0]) on stdout when run.
REAL_BINARY=`"$BINARY"`
# On cygwin, we may need to add a '.exe' extension by hand.
[ -f "$REAL_BINARY.exe" ] && REAL_BINARY="$REAL_BINARY.exe"
if strings "$REAL_BINARY" | grep "This text should be stripped" >/dev/null 2>&1
then
echo "Text not stripped from binary like it should be: $BINARY"
exit 1
fi
# Let's also do a sanity check to make sure strings is working properly
if ! strings "$REAL_BINARY" | grep "Usage message" >/dev/null 2>&1
then
echo "Usage text not found in binary like it should be: $BINARY"
exit 1
fi
fi
echo "PASS"
......@@ -35,11 +35,6 @@
#include "config_for_unittests.h"
#include <gflags/gflags.h>
#ifndef GFLAGS_SHARED_LIBS
# undef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG
#endif
#include <math.h> // for isinf() and isnan()
#include <stdio.h>
#include <stdlib.h>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment