Commit 917f4e7b authored by Craig Silverstein's avatar Craig Silverstein

Some reorganization that results from a new method I'm moving to to

maintaining this opensource tree.  Some of this reorganization is
entirely a result of reorganization: blank lines in a few different
places, etc.  Here are the others:

1) I've added a new file, util.h, with lots of new, helpful routines,
most notably StringPrintf (printf returning a string).  I've also
moved some routines from the .cc and unittest.cc file here, such as
the CHECK macros, testing framework, and #ifdefs for 16-bit ints.
Quite a bit of code was rewritten to use these new routines.

2) I noticed that the special-case setenv() code was only needed for
windows systems, so I moved it to port.h/cc.

3) I also had to add a new vsnprintf wrapper in port.h/cc, to support
StringPrintf.

4) A few places I used an old name, commandlineflags, instead of
gflags.  Most or all of these should be fixed now.

5) Some of my copyright dates weren't quite right.  Fixed them up.

6) In some .cc files, I added using directives to not have to use
std:: so much.

7) I've added a minor new test, adding 10000 or so flags to see how
the system scales.

8) Some compile-warning fixes, such as int -> size_t when appropriate,
and better protected #defines in mutex.h

9) The .h files gained some logic defining GFLAGS_DLL_DECL.  This is
true even for .h files outside the windows directory, which will never
have these dll issues.  But one big advantage of my new organization
is auto-generating the windows versions of these files from the unix
versions, so there's some unnecessary (but harmless) duplication as a
result.

10) Fixed a bug in rpm.sh which would cause an unnecessary crash when
dpkg was missing.


git-svn-id: https://gflags.googlecode.com/svn/trunk@52 6586e3c6-dcc4-952a-343f-ff74eb82781d
parent b7ea0659
...@@ -56,7 +56,7 @@ CLEANFILES = ...@@ -56,7 +56,7 @@ CLEANFILES =
## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS ## vvvv RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
GFLAGS_SOURCES = $(gflagsinclude_HEADERS) src/mutex.h \ GFLAGS_SOURCES = $(gflagsinclude_HEADERS) src/mutex.h src/util.h \
src/gflags.cc src/gflags_reporting.cc \ src/gflags.cc src/gflags_reporting.cc \
src/gflags_completions.cc src/gflags_completions.cc
......
This diff is collapsed.
This diff is collapsed.
...@@ -55,6 +55,8 @@ AC_CHECK_HEADER(stdint.h, ac_cv_have_stdint_h=1, ac_cv_have_stdint_h=0) ...@@ -55,6 +55,8 @@ AC_CHECK_HEADER(stdint.h, ac_cv_have_stdint_h=1, ac_cv_have_stdint_h=0)
AC_CHECK_HEADER(sys/types.h, ac_cv_have_systypes_h=1, ac_cv_have_systypes_h=0) AC_CHECK_HEADER(sys/types.h, ac_cv_have_systypes_h=1, ac_cv_have_systypes_h=0)
AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0) AC_CHECK_HEADER(inttypes.h, ac_cv_have_inttypes_h=1, ac_cv_have_inttypes_h=0)
AC_CHECK_HEADERS([fnmatch.h]) AC_CHECK_HEADERS([fnmatch.h])
AC_CHECK_HEADERS([sys/stat.h])
AC_CHECK_HEADERS([unistd.h])
# These are the types I need. We look for them in either stdint.h, # These are the types I need. We look for them in either stdint.h,
# sys/types.h, or inttypes.h, all of which are part of the default-includes. # sys/types.h, or inttypes.h, all of which are part of the default-includes.
...@@ -63,7 +65,6 @@ AC_CHECK_TYPE(u_int16_t, ac_cv_have_u_int16_t=1, ac_cv_have_u_int16_t=0) ...@@ -63,7 +65,6 @@ AC_CHECK_TYPE(u_int16_t, ac_cv_have_u_int16_t=1, ac_cv_have_u_int16_t=0)
AC_CHECK_TYPE(__int16, ac_cv_have___int16=1, ac_cv_have___int16=0) AC_CHECK_TYPE(__int16, ac_cv_have___int16=1, ac_cv_have___int16=0)
AC_CHECK_FUNCS([strtoll strtoq]) AC_CHECK_FUNCS([strtoll strtoq])
AC_CHECK_FUNCS([setenv putenv]) # MinGW has putenv but not setenv
AX_C___ATTRIBUTE__ AX_C___ATTRIBUTE__
# We only care about __attribute__ ((unused)) # We only care about __attribute__ ((unused))
......
...@@ -52,7 +52,7 @@ cp "$archive" "$RPM_SOURCE_DIR" ...@@ -52,7 +52,7 @@ cp "$archive" "$RPM_SOURCE_DIR"
# does a better job of this, so if we can run 'dpkg --print-architecture' # does a better job of this, so if we can run 'dpkg --print-architecture'
# to get the build CPU, we use that in preference of the rpmbuild # to get the build CPU, we use that in preference of the rpmbuild
# default. # default.
target=`dpkg --print-architecture 2>/dev/null` # "" if dpkg isn't found target=`dpkg --print-architecture 2>/dev/null || echo ""`
if [ -n "$target" ] if [ -n "$target" ]
then then
target=" --target $target" target=" --target $target"
......
...@@ -28,12 +28,6 @@ ...@@ -28,12 +28,6 @@
/* Define if you have POSIX threads libraries and header files. */ /* Define if you have POSIX threads libraries and header files. */
#undef HAVE_PTHREAD #undef HAVE_PTHREAD
/* Define to 1 if you have the `putenv' function. */
#undef HAVE_PUTENV
/* Define to 1 if you have the `setenv' function. */
#undef HAVE_SETENV
/* Define to 1 if you have the <stdint.h> header file. */ /* Define to 1 if you have the <stdint.h> header file. */
#undef HAVE_STDINT_H #undef HAVE_STDINT_H
...@@ -83,9 +77,6 @@ ...@@ -83,9 +77,6 @@
/* Define to the one symbol short name of this package. */ /* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME #undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */ /* Define to the version of this package. */
#undef PACKAGE_VERSION #undef PACKAGE_VERSION
......
...@@ -30,7 +30,6 @@ ...@@ -30,7 +30,6 @@
// --- // ---
// All Rights Reserved. // All Rights Reserved.
// //
// Author: Craig Silverstein
// //
// This file is needed for windows -- unittests are not part of the // This file is needed for windows -- unittests are not part of the
// gflags dll, but still want to include config.h just like the // gflags dll, but still want to include config.h just like the
......
This diff is collapsed.
This diff is collapsed.
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// --- // ---
// Author: Dave Nicponski
// //
// Implement helpful bash-style command line flag completions // Implement helpful bash-style command line flag completions
// //
...@@ -88,8 +88,8 @@ ...@@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ): // file would be (your path to gflags_completions.sh file may differ):
/* /*
$ complete -o bashdefault -o default -o nospace -C \ $ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...] time env binary_name another_binary [...]
*/ */
...@@ -109,13 +109,27 @@ $ complete -o bashdefault -o default -o nospace -C \ ...@@ -109,13 +109,27 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output. // produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ #ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_ #define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
// Annoying stuff for windows -- makes sure clients can import these functions
//
// NOTE: all functions below MUST have an explicit 'extern' before
// them. Our automated opensourcing tools use this as a signal to do
// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
//
#ifndef GFLAGS_DLL_DECL
# ifdef _WIN32
# define GFLAGS_DLL_DECL __declspec(dllimport)
# else
# define GFLAGS_DLL_DECL /**/
# endif
#endif
@ac_google_start_namespace@ @ac_google_start_namespace@
void HandleCommandLineCompletions(void); extern void HandleCommandLineCompletions(void);
@ac_google_end_namespace@ @ac_google_end_namespace@
#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ #endif // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
// Copyright (c) 2011, Google Inc. // Copyright (c) 1999, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --- // ---
// Author: Ray Sidney //
// Revamped and reorganized by Craig Silverstein // Revamped and reorganized by Craig Silverstein
// //
// This is the file that should be included by any file which declares // This is the file that should be included by any file which declares
...@@ -38,35 +38,17 @@ ...@@ -38,35 +38,17 @@
#define BASE_COMMANDLINEFLAGS_DECLARE_H_ #define BASE_COMMANDLINEFLAGS_DECLARE_H_
#include <string> #include <string>
// We care a lot about number of bits things take up. Unfortunately,
// systems define their bit-specific ints in a lot of different ways.
// We use our own way, and have a typedef to get there.
// Note: these commands below may look like "#if 1" or "#if 0", but
// that's because they were constructed that way at ./configure time.
// Look at gflags.h.in to see how they're calculated (based on your config).
#if @ac_cv_have_stdint_h@ #if @ac_cv_have_stdint_h@
#include <stdint.h> // the normal place uint16_t is defined #include <stdint.h> // the normal place uint16_t is defined
#endif #endif
#if @ac_cv_have_systypes_h@ #if @ac_cv_have_systypes_h@
#include <sys/types.h> // the normal place u_int16_t is defined #include <sys/types.h> // the normal place u_int16_t is defined
#endif #endif
#if @ac_cv_have_inttypes_h@ #if @ac_cv_have_inttypes_h@
#include <inttypes.h> // a third place for uint16_t or u_int16_t #include <inttypes.h> // a third place for uint16_t or u_int16_t
#endif #endif
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;
}
@ac_google_start_namespace@ @ac_google_start_namespace@
#if @ac_cv_have_uint16_t@ // the C99 format #if @ac_cv_have_uint16_t@ // the C99 format
typedef int32_t int32; typedef int32_t int32;
typedef uint32_t uint32; typedef uint32_t uint32;
...@@ -85,22 +67,66 @@ typedef unsigned __int64 uint64; ...@@ -85,22 +67,66 @@ typedef unsigned __int64 uint64;
#else #else
#error Do not know how to define a 32-bit integer quantity on your system #error Do not know how to define a 32-bit integer quantity on your system
#endif #endif
@ac_google_end_namespace@ @ac_google_end_namespace@
// Annoying stuff for windows -- makes sure clients can import these functions
#if defined(_WIN32)
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# endif
#else
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL /**/
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG /**/
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG /**/
# endif
#endif
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;
}
#define DECLARE_VARIABLE(type, shorttype, name) \ #define DECLARE_VARIABLE(type, shorttype, name) \
namespace fL##shorttype { extern type FLAGS_##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 using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name) #define DECLARE_bool(name) \
#define DECLARE_int32(name) DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name) DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int64(name) DECLARE_VARIABLE(@ac_google_namespace@::int64, I64, name)
#define DECLARE_uint64(name) DECLARE_VARIABLE(@ac_google_namespace@::uint64, U64, name) #define DECLARE_int32(name) \
#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name) DECLARE_VARIABLE(@ac_google_namespace@::int32, I, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(@ac_google_namespace@::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(@ac_google_namespace@::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \ #define DECLARE_string(name) \
namespace fLS { \ namespace fLS { \
using ::fLS::clstring; \ using ::fLS::clstring; \
extern ::fLS::clstring& FLAGS_##name; \ extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \ } \
using fLS::FLAGS_##name using fLS::FLAGS_##name
......
This diff is collapsed.
...@@ -50,12 +50,12 @@ ...@@ -50,12 +50,12 @@
completion_word_index="$(($# - 1))" completion_word_index="$(($# - 1))"
completion_word="${!completion_word_index}" completion_word="${!completion_word_index}"
# TODO(daven): Replace this once commandlineflags_completions.cc has # TODO(user): Replace this once gflags_completions.cc has
# a bool parameter indicating unambiguously to hijack the process for # a bool parameter indicating unambiguously to hijack the process for
# completion purposes. # completion purposes.
if [ -z "$completion_word" ]; then if [ -z "$completion_word" ]; then
# Until an empty value for the completion word stops being misunderstood # Until an empty value for the completion word stops being misunderstood
# by google3 binaries, don't actuall execute the binary or the process # by binaries, don't actually execute the binary or the process
# won't be hijacked! # won't be hijacked!
exit 0 exit 0
fi fi
...@@ -74,12 +74,10 @@ binary="${!binary_index}" ...@@ -74,12 +74,10 @@ binary="${!binary_index}"
# places this in the $COMP_LINE variable. # places this in the $COMP_LINE variable.
if [ "$binary" == "time" ] || [ "$binary" == "env" ]; then if [ "$binary" == "time" ] || [ "$binary" == "env" ]; then
# we'll assume that the first 'argument' is actually the # we'll assume that the first 'argument' is actually the
# binary to be run, if we think it looks like a google3
# binary # binary
# TODO(daven): Decide what 'looks' like a google3 binary. =)
# TODO(daven): This is not perfect - the 'env' command, for instance, # TODO(user): This is not perfect - the 'env' command, for instance,
# is allowed to have options between the 'env' and 'the command to # is allowed to have options between the 'env' and 'the command to
# be executed'. For example, consider: # be executed'. For example, consider:
# $ env FOO="bar" bin/do_something --help<TAB> # $ env FOO="bar" bin/do_something --help<TAB>
...@@ -105,7 +103,7 @@ for ((i=1; i<=$(($# - 3)); ++i)); do ...@@ -105,7 +103,7 @@ for ((i=1; i<=$(($# - 3)); ++i)); do
done done
params="$params --tab_completion_word \"$completion_word\"" params="$params --tab_completion_word \"$completion_word\""
# TODO(daven): Perhaps stash the output in a temporary file somewhere # TODO(user): Perhaps stash the output in a temporary file somewhere
# in /tmp, and only cat it to stdout if the command returned a success # in /tmp, and only cat it to stdout if the command returned a success
# code, to prevent false positives # code, to prevent false positives
......
...@@ -28,9 +28,8 @@ ...@@ -28,9 +28,8 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --- // ---
// Author: Roberto Bayardo
// //
// A negative compile test for commandlineflags. // A negative comiple test for gflags.
#include <gflags/gflags.h> #include <gflags/gflags.h>
......
// Copyright (c) 2006, Google Inc. // Copyright (c) 1999, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --- // ---
// Author: Ray Sidney //
// Revamped and reorganized by Craig Silverstein // Revamped and reorganized by Craig Silverstein
// //
// This file contains code for handling the 'reporting' flags. These // This file contains code for handling the 'reporting' flags. These
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
// HandleCommandLineHelpFlags(). (Well, actually, ShowUsageWithFlags(), // HandleCommandLineHelpFlags(). (Well, actually, ShowUsageWithFlags(),
// ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called // ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called
// externally too, but there's little need for it.) These are all // externally too, but there's little need for it.) These are all
// declared in the main commandlineflags.h header file. // declared in the main gflags.h header file.
// //
// HandleCommandLineHelpFlags() will check what 'reporting' flags have // HandleCommandLineHelpFlags() will check what 'reporting' flags have
// been defined, if any -- the "help" part of the function name is a // been defined, if any -- the "help" part of the function name is a
...@@ -48,7 +48,7 @@ ...@@ -48,7 +48,7 @@
// called after all flag-values have been assigned, that is, after // called after all flag-values have been assigned, that is, after
// parsing the command-line. // parsing the command-line.
#include "config.h" #include <config.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
...@@ -57,12 +57,13 @@ ...@@ -57,12 +57,13 @@
#include <vector> #include <vector>
#include <gflags/gflags.h> #include <gflags/gflags.h>
#include <gflags/gflags_completions.h> #include <gflags/gflags_completions.h>
#include "util.h"
#ifndef PATH_SEPARATOR #ifndef PATH_SEPARATOR
#define PATH_SEPARATOR '/' #define PATH_SEPARATOR '/'
#endif #endif
// The 'reporting' flags. They all call exit(). // The 'reporting' flags. They all call gflags_exitfunc().
DEFINE_bool(help, false, DEFINE_bool(help, false,
"show help on all flags [tip: all flags can have two dashes]"); "show help on all flags [tip: all flags can have two dashes]");
DEFINE_bool(helpfull, false, DEFINE_bool(helpfull, false,
...@@ -85,11 +86,12 @@ _START_GOOGLE_NAMESPACE_ ...@@ -85,11 +86,12 @@ _START_GOOGLE_NAMESPACE_
using std::string; using std::string;
using std::vector; using std::vector;
// -------------------------------------------------------------------- // --------------------------------------------------------------------
// DescribeOneFlag() // DescribeOneFlag()
// DescribeOneFlagInXML() // DescribeOneFlagInXML()
// Routines that pretty-print info about a flag. These use // Routines that pretty-print info about a flag. These use
// a CommandLineFlagInfo, which is the way the commandlineflags // a CommandLineFlagInfo, which is the way the gflags
// API exposes static info about a flag. // API exposes static info about a flag.
// -------------------------------------------------------------------- // --------------------------------------------------------------------
...@@ -114,17 +116,19 @@ static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag, ...@@ -114,17 +116,19 @@ static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag,
const char* c_string = (current ? flag.current_value.c_str() : const char* c_string = (current ? flag.current_value.c_str() :
flag.default_value.c_str()); flag.default_value.c_str());
if (strcmp(flag.type.c_str(), "string") == 0) { // add quotes for strings if (strcmp(flag.type.c_str(), "string") == 0) { // add quotes for strings
return text + ": \"" + c_string + "\""; return StringPrintf("%s: \"%s\"", text.c_str(), c_string);
} else { } else {
return text + ": " + c_string; return StringPrintf("%s: %s", text.c_str(), c_string);
} }
} }
// Create a descriptive string for a flag. // Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks. // Goes to some trouble to make pretty line breaks.
string DescribeOneFlag(const CommandLineFlagInfo& flag) { string DescribeOneFlag(const CommandLineFlagInfo& flag) {
string main_part = (string(" -") + flag.name + string main_part;
" (" + flag.description + ')'); SStringPrintf(&main_part, " -%s (%s)",
flag.name.c_str(),
flag.description.c_str());
const char* c_string = main_part.c_str(); const char* c_string = main_part.c_str();
int chars_left = static_cast<int>(main_part.length()); int chars_left = static_cast<int>(main_part.length());
string final_string = ""; string final_string = "";
...@@ -164,7 +168,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) { ...@@ -164,7 +168,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
} }
if (*c_string == '\0') if (*c_string == '\0')
break; break;
final_string += "\n "; StringAppendF(&final_string, "\n ");
chars_in_line = 6; chars_in_line = 6;
} }
...@@ -173,7 +177,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) { ...@@ -173,7 +177,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
// The listed default value will be the actual default from the flag // The listed default value will be the actual default from the flag
// definition in the originating source file, unless the value has // definition in the originating source file, unless the value has
// subsequently been modified using SetCommandLineOptionWithMode() with mode // subsequently been modified using SetCommandLineOptionWithMode() with mode
// SET_FLAGS_DEFAULT, or by setting FLAGS_foo = bar before initializing. // SET_FLAGS_DEFAULT, or by setting FLAGS_foo = bar before ParseCommandLineFlags().
AddString(PrintStringFlagsWithQuotes(flag, "default", false), &final_string, AddString(PrintStringFlagsWithQuotes(flag, "default", false), &final_string,
&chars_in_line); &chars_in_line);
if (!flag.is_default) { if (!flag.is_default) {
...@@ -181,7 +185,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) { ...@@ -181,7 +185,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
&final_string, &chars_in_line); &final_string, &chars_in_line);
} }
final_string += '\n'; StringAppendF(&final_string, "\n");
return final_string; return final_string;
} }
...@@ -196,15 +200,10 @@ static string XMLText(const string& txt) { ...@@ -196,15 +200,10 @@ static string XMLText(const string& txt) {
} }
static void AddXMLTag(string* r, const char* tag, const string& txt) { static void AddXMLTag(string* r, const char* tag, const string& txt) {
*r += ('<'); StringAppendF(r, "<%s>%s</%s>", tag, XMLText(txt).c_str(), tag);
*r += (tag);
*r += ('>');
*r += (XMLText(txt));
*r += ("</");
*r += (tag);
*r += ('>');
} }
static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) { static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) {
// The file and flagname could have been attributes, but default // The file and flagname could have been attributes, but default
// and meaning need to avoid attribute normalization. This way it // and meaning need to avoid attribute normalization. This way it
...@@ -265,9 +264,9 @@ static bool FileMatchesSubstring(const string& filename, ...@@ -265,9 +264,9 @@ static bool FileMatchesSubstring(const string& filename,
// Show help for every filename which matches any of the target substrings. // Show help for every filename which matches any of the target substrings.
// If substrings is empty, shows help for every file. If a flag's help message // If substrings is empty, shows help for every file. If a flag's help message
// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1' before // has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1'
// including gflags/gflags.h), then this flag will not be displayed by // before including gflags/gflags.h), then this flag will not be displayed
// '--help' and its variants. // by '--help' and its variants.
static void ShowUsageWithFlagsMatching(const char *argv0, static void ShowUsageWithFlagsMatching(const char *argv0,
const vector<string> &substrings) { const vector<string> &substrings) {
fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage()); fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage());
...@@ -354,7 +353,6 @@ static void ShowVersion() { ...@@ -354,7 +353,6 @@ static void ShowVersion() {
} else { } else {
fprintf(stdout, "%s\n", ProgramInvocationShortName()); fprintf(stdout, "%s\n", ProgramInvocationShortName());
} }
# if !defined(NDEBUG) # if !defined(NDEBUG)
fprintf(stdout, "Debug build (NDEBUG not #defined)\n"); fprintf(stdout, "Debug build (NDEBUG not #defined)\n");
# endif # endif
...@@ -379,7 +377,6 @@ static void AppendPrognameStrings(vector<string>* substrings, ...@@ -379,7 +377,6 @@ static void AppendPrognameStrings(vector<string>* substrings,
void HandleCommandLineHelpFlags() { void HandleCommandLineHelpFlags() {
const char* progname = ProgramInvocationShortName(); const char* progname = ProgramInvocationShortName();
extern void (*commandlineflags_exitfunc)(int); // in gflags.cc
HandleCommandLineCompletions(); HandleCommandLineCompletions();
...@@ -390,21 +387,21 @@ void HandleCommandLineHelpFlags() { ...@@ -390,21 +387,21 @@ void HandleCommandLineHelpFlags() {
// show only flags related to this binary: // show only flags related to this binary:
// E.g. for fileutil.cc, want flags containing ... "/fileutil." cc // E.g. for fileutil.cc, want flags containing ... "/fileutil." cc
ShowUsageWithFlagsMatching(progname, substrings); ShowUsageWithFlagsMatching(progname, substrings);
commandlineflags_exitfunc(1); // almost certainly exit() gflags_exitfunc(1);
} else if (FLAGS_help || FLAGS_helpfull) { } else if (FLAGS_help || FLAGS_helpfull) {
// show all options // show all options
ShowUsageWithFlagsRestrict(progname, ""); // empty restrict ShowUsageWithFlagsRestrict(progname, ""); // empty restrict
commandlineflags_exitfunc(1); gflags_exitfunc(1);
} else if (!FLAGS_helpon.empty()) { } else if (!FLAGS_helpon.empty()) {
string restrict = "/" + FLAGS_helpon + "."; string restrict = "/" + FLAGS_helpon + ".";
ShowUsageWithFlagsRestrict(progname, restrict.c_str()); ShowUsageWithFlagsRestrict(progname, restrict.c_str());
commandlineflags_exitfunc(1); gflags_exitfunc(1);
} else if (!FLAGS_helpmatch.empty()) { } else if (!FLAGS_helpmatch.empty()) {
ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str()); ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str());
commandlineflags_exitfunc(1); gflags_exitfunc(1);
} else if (FLAGS_helppackage) { } else if (FLAGS_helppackage) {
// Shows help for all files in the same directory as main(). We // Shows help for all files in the same directory as main(). We
...@@ -423,27 +420,27 @@ void HandleCommandLineHelpFlags() { ...@@ -423,27 +420,27 @@ void HandleCommandLineHelpFlags() {
const string package = Dirname(flag->filename) + "/"; const string package = Dirname(flag->filename) + "/";
if (package != last_package) { if (package != last_package) {
ShowUsageWithFlagsRestrict(progname, package.c_str()); ShowUsageWithFlagsRestrict(progname, package.c_str());
VLOG(7) << "Found package: " << package;
if (!last_package.empty()) { // means this isn't our first pkg if (!last_package.empty()) { // means this isn't our first pkg
fprintf(stderr, "WARNING: Multiple packages contain a file=%s\n", LOG(WARNING) << "Multiple packages contain a file=" << progname;
progname);
} }
last_package = package; last_package = package;
} }
} }
if (last_package.empty()) { // never found a package to print if (last_package.empty()) { // never found a package to print
fprintf(stderr, "WARNING: Unable to find a package for file=%s\n", LOG(WARNING) << "Unable to find a package for file=" << progname;
progname);
} }
commandlineflags_exitfunc(1); gflags_exitfunc(1);
} else if (FLAGS_helpxml) { } else if (FLAGS_helpxml) {
ShowXMLOfFlags(progname); ShowXMLOfFlags(progname);
commandlineflags_exitfunc(1); gflags_exitfunc(1);
} else if (FLAGS_version) { } else if (FLAGS_version) {
ShowVersion(); ShowVersion();
// Unlike help, we may be asking for version in a script, so return 0 // Unlike help, we may be asking for version in a script, so return 0
commandlineflags_exitfunc(0); gflags_exitfunc(0);
} }
} }
......
...@@ -28,20 +28,22 @@ ...@@ -28,20 +28,22 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// --- // ---
// Author: Craig Silverstein // Author: csilvers@google.com (Craig Silverstein)
// //
// A simple program that uses STRIP_FLAG_HELP. We'll have a shell // A simple program that uses STRIP_FLAG_HELP. We'll have a shell
// script that runs 'strings' over this program and makes sure // script that runs 'strings' over this program and makes sure
// that the help string is not in there. // that the help string is not in there.
#include "config_for_unittests.h" #include "config_for_unittests.h"
#include <stdio.h>
#define STRIP_FLAG_HELP 1 #define STRIP_FLAG_HELP 1
#include "gflags/gflags.h" #include <gflags/gflags.h>
#include <stdio.h>
using GOOGLE_NAMESPACE::SetUsageMessage; using GOOGLE_NAMESPACE::SetUsageMessage;
using GOOGLE_NAMESPACE::ParseCommandLineFlags; using GOOGLE_NAMESPACE::ParseCommandLineFlags;
DEFINE_bool(test, true, "This text should be stripped out"); DEFINE_bool(test, true, "This text should be stripped out");
int main(int argc, char** argv) { int main(int argc, char** argv) {
...@@ -53,6 +55,7 @@ int main(int argc, char** argv) { ...@@ -53,6 +55,7 @@ int main(int argc, char** argv) {
// under a different name. We need the 'real' executable name to run // under a different name. We need the 'real' executable name to run
// 'strings' on it, so we construct this binary to print the real // 'strings' on it, so we construct this binary to print the real
// name (argv[0]) on stdout when run. // name (argv[0]) on stdout when run.
printf("%s\n", argv[0]); puts(argv[0]);
return 0; return 0;
} }
...@@ -30,14 +30,12 @@ ...@@ -30,14 +30,12 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# #
# --- # ---
# Author: Craig Silverstein # Author: csilvers@google.com (Craig Silverstein)
if [ -z "$1" ] if [ -z "$1" ]; then
then echo "USAGE: $0 <unittest exe>"
echo "USAGE: $0 <unittest exe>" exit 1
exit 1
fi fi
BINARY="$1" BINARY="$1"
# Make sure the binary exists... # Make sure the binary exists...
...@@ -57,15 +55,15 @@ fi ...@@ -57,15 +55,15 @@ fi
# Make sure the stripped text isn't in the binary at all. # Make sure the stripped text isn't in the binary at all.
if strings --help >/dev/null 2>&1 # make sure the binary exists if strings --help >/dev/null 2>&1 # make sure the binary exists
then then
# Unfortunately, for us, libtool can replace executables with a shell # Unfortunately, for us, libtool can replace executables with a
# script that does some work before calling the 'real' executable # shell script that does some work before calling the 'real'
# under a different name. We need the 'real' executable name to run # executable under a different name. We need the 'real'
# 'strings' on it, so we construct this binary to print the real # executable name to run 'strings' on it, so we construct this
# name (argv[0]) on stdout when run. # binary to print the real name (argv[0]) on stdout when run.
REAL_BINARY=`"$BINARY"` REAL_BINARY=`"$BINARY"`
# On cygwin, we may need to add a '.exe' extension by hand. # On cygwin, we may need to add a '.exe' extension by hand.
[ -f "$REAL_BINARY.exe" ] && REAL_BINARY="$REAL_BINARY.exe" [ -f "$REAL_BINARY.exe" ] && REAL_BINARY="$REAL_BINARY.exe"
if strings "$REAL_BINARY" | grep "This text should be stripped out" >/dev/null 2>&1 if strings "$REAL_BINARY" | grep "This text should be stripped" >/dev/null 2>&1
then then
echo "Text not stripped from binary like it should be: $BINARY" echo "Text not stripped from binary like it should be: $BINARY"
exit 1 exit 1
......
This diff is collapsed.
#!/bin/sh #!/bin/bash
# Copyright (c) 2006, Google Inc. # Copyright (c) 2006, Google Inc.
# All rights reserved. # All rights reserved.
...@@ -32,21 +32,17 @@ ...@@ -32,21 +32,17 @@
# --- # ---
# Author: Craig Silverstein # Author: Craig Silverstein
# #
# Just tries to run gflags_unittest with various flags defined in # Just tries to run the gflags_unittest with various flags
# gflags.cc, and make sure they give the appropriate exit # defined in gflags.cc, and make sure they give the
# status and appropriate error message. # appropriate exit status and appropriate error message.
if [ -z "$1" ] if [ -z "$1" ]; then
then echo "USAGE: $0 <unittest exe> [top_srcdir] [tmpdir]"
echo "USAGE: $0 <unittest exe> [top_srcdir] [tmpdir]" exit 1
exit 1 fi
fi
EXE="$1" EXE="$1"
SRCDIR="${2:-./}" SRCDIR="${2:-./}"
TMPDIR="${3:-/tmp/gflags}" TMPDIR="${3:-/tmp/gflags}"
# Executables built with the main source file suffixed with "-main" and "_main".
EXE2="${EXE}2" # eg, gflags_unittest2 EXE2="${EXE}2" # eg, gflags_unittest2
EXE3="${EXE}3" # eg, gflags_unittest3 EXE3="${EXE}3" # eg, gflags_unittest3
...@@ -65,8 +61,9 @@ ExpectExe() { ...@@ -65,8 +61,9 @@ ExpectExe() {
local unexpected_output="$1" local unexpected_output="$1"
shift shift
# We always add --srcdir=$SRCDIR because it's needed for correctness # We always add --srcdir because it's needed for correctness
"$executable" --srcdir="$SRCDIR" "$@" > "$TMPDIR/test.$line_number" 2>&1 "$executable" --srcdir="$SRCDIR" "$@" > "$TMPDIR/test.$line_number" 2>&1
local actual_rc=$? local actual_rc=$?
if [ $actual_rc != $expected_rc ]; then if [ $actual_rc != $expected_rc ]; then
echo "Test on line $line_number failed:" \ echo "Test on line $line_number failed:" \
...@@ -111,7 +108,7 @@ export FLAGS_help=false ...@@ -111,7 +108,7 @@ export FLAGS_help=false
# First, just make sure the unittest works as-is # First, just make sure the unittest works as-is
Expect $LINENO 0 "PASS" "" Expect $LINENO 0 "PASS" ""
# --help should show all flags, including flags from gflags_reporting.cc # --help should show all flags, including flags from gflags_reporting
Expect $LINENO 1 "/gflags_reporting.cc" "" --help Expect $LINENO 1 "/gflags_reporting.cc" "" --help
# Make sure --help reflects flag changes made before flag-parsing # Make sure --help reflects flag changes made before flag-parsing
...@@ -133,17 +130,18 @@ Expect $LINENO 0 "PASS" "" --help=false ...@@ -133,17 +130,18 @@ Expect $LINENO 0 "PASS" "" --help=false
Expect $LINENO 1 "/gflags_reporting.cc" "" -helpfull Expect $LINENO 1 "/gflags_reporting.cc" "" -helpfull
# --helpshort should show only flags from the unittest itself # --helpshort should show only flags from the unittest itself
Expect $LINENO 1 "/gflags_unittest.cc" "/gflags_reporting.cc" --helpshort Expect $LINENO 1 "/gflags_unittest.cc" \
"/gflags_reporting.cc" --helpshort
# --helpshort should show the tldflag we created in the unittest dir # --helpshort should show the tldflag we created in the unittest dir
Expect $LINENO 1 "tldflag1" "/google.cc" --helpshort Expect $LINENO 1 "tldflag1" "/google.cc" --helpshort
Expect $LINENO 1 "tldflag2" "/google.cc" --helpshort Expect $LINENO 1 "tldflag2" "/google.cc" --helpshort
# --helpshort should work if the main source file is suffixed with [_-]main # --helpshort should work if the main source file is suffixed with [_-]main
ExpectExe "$EXE2" $LINENO 1 "/gflags_unittest-main.cc" "/gflags_reporting.cc" \ ExpectExe "$EXE2" $LINENO 1 "/gflags_unittest-main.cc" \
--helpshort "/gflags_reporting.cc" --helpshort
ExpectExe "$EXE3" $LINENO 1 "/gflags_unittest_main.cc" "/gflags_reporting.cc" \ ExpectExe "$EXE3" $LINENO 1 "/gflags_unittest_main.cc" \
--helpshort "/gflags_reporting.cc" --helpshort
# --helpon needs an argument # --helpon needs an argument
Expect $LINENO 1 \ Expect $LINENO 1 \
...@@ -151,20 +149,22 @@ Expect $LINENO 1 \ ...@@ -151,20 +149,22 @@ Expect $LINENO 1 \
"" --helpon "" --helpon
# --helpon argument indicates what file we'll show args from # --helpon argument indicates what file we'll show args from
Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" --helpon=gflags Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" \
--helpon=gflags
# another way of specifying the argument # another way of specifying the argument
Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" --helpon gflags Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" \
--helpon gflags
# test another argument # test another argument
Expect $LINENO 1 "/gflags_unittest.cc" "/gflags.cc" \ Expect $LINENO 1 "/gflags_unittest.cc" "/gflags.cc" \
--helpon gflags_unittest --helpon=gflags_unittest
# helpmatch is like helpon but takes substrings # helpmatch is like helpon but takes substrings
Expect $LINENO 1 "/gflags_reporting.cc" "/gflags_unittest.cc" \ Expect $LINENO 1 "/gflags_reporting.cc" \
-helpmatch reporting "/gflags_unittest.cc" -helpmatch reporting
Expect $LINENO 1 "/gflags_unittest.cc" "/gflags.cc" \ Expect $LINENO 1 "/gflags_unittest.cc" \
-helpmatch=unittest "/gflags.cc" -helpmatch=unittest
# if no flags are found with helpmatch or helpon, suggest --help # if no flags are found with helpmatch or helpon, suggest --help
Expect $LINENO 1 "No modules matched" "/gflags_unittest.cc" \ Expect $LINENO 1 "No modules matched" "/gflags_unittest.cc" \
...@@ -202,8 +202,10 @@ Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.2" ...@@ -202,8 +202,10 @@ Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.2"
Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.3" Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.3"
# Also try to load flags from the environment # Also try to load flags from the environment
Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" --fromenv=version Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" --tryfromenv=version --fromenv=version
Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
--tryfromenv=version
Expect $LINENO 0 "PASS" "" --fromenv=help Expect $LINENO 0 "PASS" "" --fromenv=help
Expect $LINENO 0 "PASS" "" --tryfromenv=help Expect $LINENO 0 "PASS" "" --tryfromenv=help
Expect $LINENO 1 "helpfull not found in environment" "" --fromenv=helpfull Expect $LINENO 1 "helpfull not found in environment" "" --fromenv=helpfull
...@@ -221,10 +223,11 @@ Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \ ...@@ -221,10 +223,11 @@ Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
# Make sure -- by itself stops argv processing # Make sure -- by itself stops argv processing
Expect $LINENO 0 "PASS" "" -- --help Expect $LINENO 0 "PASS" "" -- --help
# And we should die if the flag value doesn't pass the validator # And we should die if the flag value doesn't pass the validator
Expect $LINENO 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" --always_fail Expect $LINENO 1 "ERROR: failed validation of new value 'true' for flag 'always_fail'" "" --always_fail
# TODO(wojtekm) And if locking in validators fails. # TODO(user) And if locking in validators fails.
# Expect $LINENO 0 "PASS" "" --deadlock_if_cant_lock # Expect $LINENO 0 "PASS" "" --deadlock_if_cant_lock
echo "PASS" echo "PASS"
......
...@@ -28,7 +28,6 @@ ...@@ -28,7 +28,6 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// --- // ---
// Author: Craig Silverstein.
// //
// A simple mutex wrapper, supporting locks and read-write locks. // A simple mutex wrapper, supporting locks and read-write locks.
// You should assume the locks are *not* re-entrant. // You should assume the locks are *not* re-entrant.
...@@ -117,7 +116,12 @@ ...@@ -117,7 +116,12 @@
#if defined(NO_THREADS) #if defined(NO_THREADS)
typedef int MutexType; // to keep a lock-count typedef int MutexType; // to keep a lock-count
#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__) #elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
# define WIN32_LEAN_AND_MEAN // We only need minimal includes # ifndef WIN32_LEAN_AND_MEAN
# define WIN32_LEAN_AND_MEAN // We only need minimal includes
# endif
# ifndef NOMINMAX
# define NOMINMAX // Don't want windows to override min()/max()
# endif
# ifdef GMUTEX_TRYLOCK # ifdef GMUTEX_TRYLOCK
// We need Windows NT or later for TryEnterCriticalSection(). If you // We need Windows NT or later for TryEnterCriticalSection(). If you
// don't need that functionality, you can remove these _WIN32_WINNT // don't need that functionality, you can remove these _WIN32_WINNT
...@@ -134,7 +138,10 @@ ...@@ -134,7 +138,10 @@
// *does* cause problems for FreeBSD, or MacOSX, but isn't needed // *does* cause problems for FreeBSD, or MacOSX, but isn't needed
// for locking there.) // for locking there.)
# ifdef __linux__ # ifdef __linux__
# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls # if _XOPEN_SOURCE < 500 // including not being defined at all
# undef _XOPEN_SOURCE
# define _XOPEN_SOURCE 500 // may be needed to get the rwlock calls
# endif
# endif # endif
# include <pthread.h> # include <pthread.h>
typedef pthread_rwlock_t MutexType; typedef pthread_rwlock_t MutexType;
......
This diff is collapsed.
This diff is collapsed.
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// //
// --- // ---
// Author: Dave Nicponski
// //
// Implement helpful bash-style command line flag completions // Implement helpful bash-style command line flag completions
// //
...@@ -88,8 +88,8 @@ ...@@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ): // file would be (your path to gflags_completions.sh file may differ):
/* /*
$ complete -o bashdefault -o default -o nospace -C \ $ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \ '/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...] time env binary_name another_binary [...]
*/ */
...@@ -109,22 +109,27 @@ $ complete -o bashdefault -o default -o nospace -C \ ...@@ -109,22 +109,27 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output. // produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_ #ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_ #define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
// Annoying stuff for windows -- makes sure clients can import these functions // Annoying stuff for windows -- makes sure clients can import these functions
//
// NOTE: all functions below MUST have an explicit 'extern' before
// them. Our automated opensourcing tools use this as a signal to do
// appropriate munging for windows, which needs to add GFLAGS_DLL_DECL.
//
#ifndef GFLAGS_DLL_DECL #ifndef GFLAGS_DLL_DECL
# ifdef _WIN32 # ifdef _WIN32
# define GFLAGS_DLL_DECL __declspec(dllimport) # define GFLAGS_DLL_DECL __declspec(dllimport)
# else # else
# define GFLAGS_DLL_DECL # define GFLAGS_DLL_DECL /**/
# endif # endif
#endif #endif
namespace google { namespace google {
GFLAGS_DLL_DECL void HandleCommandLineCompletions(void); extern GFLAGS_DLL_DECL void HandleCommandLineCompletions(void);
} }
#endif // GOOGLE_GFLAGS_COMPLETIONS_H_ #endif // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
// Copyright (c) 2011, Google Inc. // Copyright (c) 1999, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// --- // ---
// Author: Ray Sidney //
// Revamped and reorganized by Craig Silverstein // Revamped and reorganized by Craig Silverstein
// //
// This is the file that should be included by any file which declares // This is the file that should be included by any file which declares
...@@ -38,36 +38,17 @@ ...@@ -38,36 +38,17 @@
#define BASE_COMMANDLINEFLAGS_DECLARE_H_ #define BASE_COMMANDLINEFLAGS_DECLARE_H_
#include <string> #include <string>
// We care a lot about number of bits things take up. Unfortunately,
// systems define their bit-specific ints in a lot of different ways.
// We use our own way, and have a typedef to get there.
// Note: these commands below may look like "#if 1" or "#if 0", but
// that's because they were constructed that way at ./configure time.
// Look at gflags.h.in to see how they're calculated (based on your config).
#if 0 #if 0
#include <stdint.h> // the normal place uint16_t is defined #include <stdint.h> // the normal place uint16_t is defined
#endif #endif
#if 1 #if 1
#include <sys/types.h> // the normal place u_int16_t is defined #include <sys/types.h> // the normal place u_int16_t is defined
#endif #endif
#if 0 #if 0
#include <inttypes.h> // a third place for uint16_t or u_int16_t #include <inttypes.h> // a third place for uint16_t or u_int16_t
#endif #endif
namespace google { namespace google {
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;
}
#if 0 // the C99 format #if 0 // the C99 format
typedef int32_t int32; typedef int32_t int32;
typedef uint32_t uint32; typedef uint32_t uint32;
...@@ -78,7 +59,7 @@ typedef int32_t int32; ...@@ -78,7 +59,7 @@ typedef int32_t int32;
typedef u_int32_t uint32; typedef u_int32_t uint32;
typedef int64_t int64; typedef int64_t int64;
typedef u_int64_t uint64; typedef u_int64_t uint64;
#elif 1 // the windows (vc7) format #elif 1 // the windows (vc7) format
typedef __int32 int32; typedef __int32 int32;
typedef unsigned __int32 uint32; typedef unsigned __int32 uint32;
typedef __int64 int64; typedef __int64 int64;
...@@ -86,6 +67,39 @@ typedef unsigned __int64 uint64; ...@@ -86,6 +67,39 @@ typedef unsigned __int64 uint64;
#else #else
#error Do not know how to define a 32-bit integer quantity on your system #error Do not know how to define a 32-bit integer quantity on your system
#endif #endif
}
// Annoying stuff for windows -- makes sure clients can import these functions
#if defined(_WIN32)
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
# endif
#else
# ifndef GFLAGS_DLL_DECL
# define GFLAGS_DLL_DECL /**/
# endif
# ifndef GFLAGS_DLL_DECLARE_FLAG
# define GFLAGS_DLL_DECLARE_FLAG /**/
# endif
# ifndef GFLAGS_DLL_DEFINE_FLAG
# define GFLAGS_DLL_DEFINE_FLAG /**/
# endif
#endif
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;
} }
...@@ -94,11 +108,21 @@ typedef unsigned __int64 uint64; ...@@ -94,11 +108,21 @@ typedef unsigned __int64 uint64;
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \ namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name) #define DECLARE_bool(name) \
#define DECLARE_int32(name) DECLARE_VARIABLE(google::int32, I, name) DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int64(name) DECLARE_VARIABLE(google::int64, I64, name)
#define DECLARE_uint64(name) DECLARE_VARIABLE(google::uint64, U64, name) #define DECLARE_int32(name) \
#define DECLARE_double(name) DECLARE_VARIABLE(double, D, name) DECLARE_VARIABLE(::google::int32, I, name)
#define DECLARE_int64(name) \
DECLARE_VARIABLE(::google::int64, I64, name)
#define DECLARE_uint64(name) \
DECLARE_VARIABLE(::google::uint64, U64, name)
#define DECLARE_double(name) \
DECLARE_VARIABLE(double, D, name)
#define DECLARE_string(name) \ #define DECLARE_string(name) \
namespace fLS { \ namespace fLS { \
using ::fLS::clstring; \ using ::fLS::clstring; \
......
...@@ -37,20 +37,49 @@ ...@@ -37,20 +37,49 @@
#include <config.h> #include <config.h>
#include <string.h> // for strlen(), memset(), memcmp() #include <string.h> // for strlen(), memset(), memcmp()
#include <stdlib.h> // for _putenv, etc.
#include <assert.h> #include <assert.h>
#include <stdarg.h> // for va_list, va_start, va_end #include <stdarg.h> // for va_list, va_start, va_end
#include <windows.h> #include <windows.h>
#include "port.h" #include "port.h"
#ifndef HAVE_SNPRINTF // These call the windows _vsnprintf, but always NUL-terminate.
int snprintf(char *str, size_t size, const char *format, ...) { #if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
if (size == 0) // not even room for a \0? if (size == 0) // not even room for a \0?
return -1; // not what C99 says to do, but what windows does return -1; // not what C99 says to do, but what windows does
str[size-1] = '\0';
return _vsnprintf(str, size-1, format, ap);
}
int snprintf(char *str, size_t size, const char *format, ...) {
int r;
va_list ap; va_list ap;
va_start(ap, format); va_start(ap, format);
const int r = _vsnprintf(str, size-1, format, ap); r = vsnprintf(str, size, format, ap);
va_end(ap); va_end(ap);
str[size-1] = '\0';
return r; return r;
} }
#endif #endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
void setenv(const char* name, const char* value, int) {
// In windows, it's impossible to set a variable to the empty string.
// We handle this by setting it to "0" and the NUL-ing out the \0.
// That is, we putenv("FOO=0") and then find out where in memory the
// putenv wrote "FOO=0", and change it in-place to "FOO=\0".
// c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508
static const char* const kFakeZero = "0";
if (*value == '\0')
value = kFakeZero;
// Apparently the semantics of putenv() is that the input
// must live forever, so we leak memory here. :-(
const int nameval_len = strlen(name) + 1 + strlen(value) + 1;
char* nameval = reinterpret_cast<char*>(malloc(nameval_len));
snprintf(nameval, nameval_len, "%s=%s", name, value);
_putenv(nameval);
if (value == kFakeZero) {
nameval[nameval_len - 2] = '\0'; // works when putenv() makes no copy
if (*getenv(name) != '\0')
*getenv(name) = '\0'; // works when putenv() copies nameval
}
}
...@@ -54,15 +54,23 @@ ...@@ -54,15 +54,23 @@
#include <windows.h> #include <windows.h>
#include <direct.h> /* for mkdir */ #include <direct.h> /* for mkdir */
#include <stdio.h> /* need this to override stdio's snprintf */ #include <stdio.h> /* need this to override stdio's snprintf */
#include <stdarg.h> /* util.h uses va_copy */
#include <string.h> /* for _stricmp */
#define putenv _putenv /* We can't just use _vsnprintf and _snprintf as drop-in-replacements,
* because they don't always NUL-terminate. :-( We also can't use the
// ----------------------------------- STRING ROUTINES * name vsnprintf, since windows defines that (but not snprintf (!)).
*/
// We can't just use _snprintf as a drop-in-replacement, because it #if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
// doesn't always NUL-terminate. :-(
extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size, extern GFLAGS_DLL_DECL int snprintf(char *str, size_t size,
const char *format, ...); const char *format, ...);
extern int GFLAGS_DLL_DECL safe_vsnprintf(char *str, size_t size,
const char *format, va_list ap);
#define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap)
#define va_copy(dst, src) (dst) = (src)
#endif /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
extern void GFLAGS_DLL_DECL setenv(const char* name, const char* value, int);
#define strcasecmp _stricmp #define strcasecmp _stricmp
......
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