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 =
## 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_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)
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_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,
# 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)
AC_CHECK_TYPE(__int16, ac_cv_have___int16=1, ac_cv_have___int16=0)
AC_CHECK_FUNCS([strtoll strtoq])
AC_CHECK_FUNCS([setenv putenv]) # MinGW has putenv but not setenv
AX_C___ATTRIBUTE__
# We only care about __attribute__ ((unused))
......
......@@ -52,7 +52,7 @@ cp "$archive" "$RPM_SOURCE_DIR"
# 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
# default.
target=`dpkg --print-architecture 2>/dev/null` # "" if dpkg isn't found
target=`dpkg --print-architecture 2>/dev/null || echo ""`
if [ -n "$target" ]
then
target=" --target $target"
......
......@@ -28,12 +28,6 @@
/* Define if you have POSIX threads libraries and header files. */
#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. */
#undef HAVE_STDINT_H
......@@ -83,9 +77,6 @@
/* Define to the one symbol short name of this package. */
#undef PACKAGE_TARNAME
/* Define to the home page for this package. */
#undef PACKAGE_URL
/* Define to the version of this package. */
#undef PACKAGE_VERSION
......
......@@ -30,7 +30,6 @@
// ---
// All Rights Reserved.
//
// Author: Craig Silverstein
//
// This file is needed for windows -- unittests are not part of 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 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---
// Author: Dave Nicponski
//
// Implement helpful bash-style command line flag completions
//
......@@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ):
/*
$ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
$ complete -o bashdefault -o default -o nospace -C \
'/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...]
*/
......@@ -109,13 +109,27 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_
#ifndef BASE_COMMANDLINEFLAGS_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@
void HandleCommandLineCompletions(void);
extern void HandleCommandLineCompletions(void);
@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.
//
// Redistribution and use in source and binary forms, with or without
......@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Author: Ray Sidney
//
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
......@@ -38,35 +38,17 @@
#define BASE_COMMANDLINEFLAGS_DECLARE_H_
#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@
#include <stdint.h> // the normal place uint16_t is defined
#include <stdint.h> // the normal place uint16_t is defined
#endif
#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
#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
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@
#if @ac_cv_have_uint16_t@ // the C99 format
typedef int32_t int32;
typedef uint32_t uint32;
......@@ -85,22 +67,66 @@ typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
@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) \
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
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(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_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(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) \
namespace fLS { \
using ::fLS::clstring; \
extern ::fLS::clstring& FLAGS_##name; \
extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
} \
using fLS::FLAGS_##name
......
This diff is collapsed.
......@@ -50,12 +50,12 @@
completion_word_index="$(($# - 1))"
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
# completion purposes.
if [ -z "$completion_word" ]; then
# 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!
exit 0
fi
......@@ -74,12 +74,10 @@ binary="${!binary_index}"
# places this in the $COMP_LINE variable.
if [ "$binary" == "time" ] || [ "$binary" == "env" ]; then
# we'll assume that the first 'argument' is actually the
# binary to be run, if we think it looks like a google3
# 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
# be executed'. For example, consider:
# $ env FOO="bar" bin/do_something --help<TAB>
......@@ -105,7 +103,7 @@ for ((i=1; i<=$(($# - 3)); ++i)); do
done
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
# code, to prevent false positives
......
......@@ -28,9 +28,8 @@
// 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>
......
// Copyright (c) 2006, Google Inc.
// Copyright (c) 1999, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
......@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Author: Ray Sidney
//
// Revamped and reorganized by Craig Silverstein
//
// This file contains code for handling the 'reporting' flags. These
......@@ -40,7 +40,7 @@
// HandleCommandLineHelpFlags(). (Well, actually, ShowUsageWithFlags(),
// ShowUsageWithFlagsRestrict(), and DescribeOneFlag() can be called
// 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
// been defined, if any -- the "help" part of the function name is a
......@@ -48,7 +48,7 @@
// called after all flag-values have been assigned, that is, after
// parsing the command-line.
#include "config.h"
#include <config.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
......@@ -57,12 +57,13 @@
#include <vector>
#include <gflags/gflags.h>
#include <gflags/gflags_completions.h>
#include "util.h"
#ifndef PATH_SEPARATOR
#define PATH_SEPARATOR '/'
#endif
// The 'reporting' flags. They all call exit().
// The 'reporting' flags. They all call gflags_exitfunc().
DEFINE_bool(help, false,
"show help on all flags [tip: all flags can have two dashes]");
DEFINE_bool(helpfull, false,
......@@ -85,11 +86,12 @@ _START_GOOGLE_NAMESPACE_
using std::string;
using std::vector;
// --------------------------------------------------------------------
// DescribeOneFlag()
// DescribeOneFlagInXML()
// 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.
// --------------------------------------------------------------------
......@@ -114,17 +116,19 @@ static string PrintStringFlagsWithQuotes(const CommandLineFlagInfo& flag,
const char* c_string = (current ? flag.current_value.c_str() :
flag.default_value.c_str());
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 {
return text + ": " + c_string;
return StringPrintf("%s: %s", text.c_str(), c_string);
}
}
// Create a descriptive string for a flag.
// Goes to some trouble to make pretty line breaks.
string DescribeOneFlag(const CommandLineFlagInfo& flag) {
string main_part = (string(" -") + flag.name +
" (" + flag.description + ')');
string main_part;
SStringPrintf(&main_part, " -%s (%s)",
flag.name.c_str(),
flag.description.c_str());
const char* c_string = main_part.c_str();
int chars_left = static_cast<int>(main_part.length());
string final_string = "";
......@@ -164,7 +168,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
}
if (*c_string == '\0')
break;
final_string += "\n ";
StringAppendF(&final_string, "\n ");
chars_in_line = 6;
}
......@@ -173,7 +177,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
// The listed default value will be the actual default from the flag
// definition in the originating source file, unless the value has
// 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,
&chars_in_line);
if (!flag.is_default) {
......@@ -181,7 +185,7 @@ string DescribeOneFlag(const CommandLineFlagInfo& flag) {
&final_string, &chars_in_line);
}
final_string += '\n';
StringAppendF(&final_string, "\n");
return final_string;
}
......@@ -196,15 +200,10 @@ static string XMLText(const string& txt) {
}
static void AddXMLTag(string* r, const char* tag, const string& txt) {
*r += ('<');
*r += (tag);
*r += ('>');
*r += (XMLText(txt));
*r += ("</");
*r += (tag);
*r += ('>');
StringAppendF(r, "<%s>%s</%s>", tag, XMLText(txt).c_str(), tag);
}
static string DescribeOneFlagInXML(const CommandLineFlagInfo& flag) {
// The file and flagname could have been attributes, but default
// and meaning need to avoid attribute normalization. This way it
......@@ -265,9 +264,9 @@ static bool FileMatchesSubstring(const string& filename,
// 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
// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1' before
// including gflags/gflags.h), then this flag will not be displayed by
// '--help' and its variants.
// has been stripped (e.g. by adding '#define STRIP_FLAG_HELP 1'
// before including gflags/gflags.h), then this flag will not be displayed
// by '--help' and its variants.
static void ShowUsageWithFlagsMatching(const char *argv0,
const vector<string> &substrings) {
fprintf(stdout, "%s: %s\n", Basename(argv0), ProgramUsage());
......@@ -354,7 +353,6 @@ static void ShowVersion() {
} else {
fprintf(stdout, "%s\n", ProgramInvocationShortName());
}
# if !defined(NDEBUG)
fprintf(stdout, "Debug build (NDEBUG not #defined)\n");
# endif
......@@ -379,7 +377,6 @@ static void AppendPrognameStrings(vector<string>* substrings,
void HandleCommandLineHelpFlags() {
const char* progname = ProgramInvocationShortName();
extern void (*commandlineflags_exitfunc)(int); // in gflags.cc
HandleCommandLineCompletions();
......@@ -390,21 +387,21 @@ void HandleCommandLineHelpFlags() {
// show only flags related to this binary:
// E.g. for fileutil.cc, want flags containing ... "/fileutil." cc
ShowUsageWithFlagsMatching(progname, substrings);
commandlineflags_exitfunc(1); // almost certainly exit()
gflags_exitfunc(1);
} else if (FLAGS_help || FLAGS_helpfull) {
// show all options
ShowUsageWithFlagsRestrict(progname, ""); // empty restrict
commandlineflags_exitfunc(1);
gflags_exitfunc(1);
} else if (!FLAGS_helpon.empty()) {
string restrict = "/" + FLAGS_helpon + ".";
ShowUsageWithFlagsRestrict(progname, restrict.c_str());
commandlineflags_exitfunc(1);
gflags_exitfunc(1);
} else if (!FLAGS_helpmatch.empty()) {
ShowUsageWithFlagsRestrict(progname, FLAGS_helpmatch.c_str());
commandlineflags_exitfunc(1);
gflags_exitfunc(1);
} else if (FLAGS_helppackage) {
// Shows help for all files in the same directory as main(). We
......@@ -423,27 +420,27 @@ void HandleCommandLineHelpFlags() {
const string package = Dirname(flag->filename) + "/";
if (package != last_package) {
ShowUsageWithFlagsRestrict(progname, package.c_str());
VLOG(7) << "Found package: " << package;
if (!last_package.empty()) { // means this isn't our first pkg
fprintf(stderr, "WARNING: Multiple packages contain a file=%s\n",
progname);
LOG(WARNING) << "Multiple packages contain a file=" << progname;
}
last_package = package;
}
}
if (last_package.empty()) { // never found a package to print
fprintf(stderr, "WARNING: Unable to find a package for file=%s\n",
progname);
LOG(WARNING) << "Unable to find a package for file=" << progname;
}
commandlineflags_exitfunc(1);
gflags_exitfunc(1);
} else if (FLAGS_helpxml) {
ShowXMLOfFlags(progname);
commandlineflags_exitfunc(1);
gflags_exitfunc(1);
} else if (FLAGS_version) {
ShowVersion();
// Unlike help, we may be asking for version in a script, so return 0
commandlineflags_exitfunc(0);
gflags_exitfunc(0);
}
}
......
......@@ -28,20 +28,22 @@
// 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
// script that runs 'strings' over this program and makes sure
// that the help string is not in there.
#include "config_for_unittests.h"
#include <stdio.h>
#define STRIP_FLAG_HELP 1
#include "gflags/gflags.h"
#include <gflags/gflags.h>
#include <stdio.h>
using GOOGLE_NAMESPACE::SetUsageMessage;
using GOOGLE_NAMESPACE::ParseCommandLineFlags;
DEFINE_bool(test, true, "This text should be stripped out");
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
// 'strings' on it, so we construct this binary to print the real
// name (argv[0]) on stdout when run.
printf("%s\n", argv[0]);
puts(argv[0]);
return 0;
}
......@@ -30,14 +30,12 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# ---
# Author: Craig Silverstein
# Author: csilvers@google.com (Craig Silverstein)
if [ -z "$1" ]
then
echo "USAGE: $0 <unittest exe>"
exit 1
if [ -z "$1" ]; then
echo "USAGE: $0 <unittest exe>"
exit 1
fi
BINARY="$1"
# Make sure the binary exists...
......@@ -57,15 +55,15 @@ 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.
# 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 out" >/dev/null 2>&1
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
......
This diff is collapsed.
#!/bin/sh
#!/bin/bash
# Copyright (c) 2006, Google Inc.
# All rights reserved.
......@@ -32,21 +32,17 @@
# ---
# Author: Craig Silverstein
#
# Just tries to run gflags_unittest with various flags defined in
# gflags.cc, and make sure they give the appropriate exit
# status and appropriate error message.
if [ -z "$1" ]
then
echo "USAGE: $0 <unittest exe> [top_srcdir] [tmpdir]"
exit 1
fi
# Just tries to run the gflags_unittest with various flags
# defined in gflags.cc, and make sure they give the
# appropriate exit status and appropriate error message.
if [ -z "$1" ]; then
echo "USAGE: $0 <unittest exe> [top_srcdir] [tmpdir]"
exit 1
fi
EXE="$1"
SRCDIR="${2:-./}"
TMPDIR="${3:-/tmp/gflags}"
# Executables built with the main source file suffixed with "-main" and "_main".
EXE2="${EXE}2" # eg, gflags_unittest2
EXE3="${EXE}3" # eg, gflags_unittest3
......@@ -65,8 +61,9 @@ ExpectExe() {
local unexpected_output="$1"
shift
# We always add --srcdir=$SRCDIR because it's needed for correctness
"$executable" --srcdir="$SRCDIR" "$@" > "$TMPDIR/test.$line_number" 2>&1
# We always add --srcdir because it's needed for correctness
"$executable" --srcdir="$SRCDIR" "$@" > "$TMPDIR/test.$line_number" 2>&1
local actual_rc=$?
if [ $actual_rc != $expected_rc ]; then
echo "Test on line $line_number failed:" \
......@@ -111,7 +108,7 @@ export FLAGS_help=false
# First, just make sure the unittest works as-is
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
# Make sure --help reflects flag changes made before flag-parsing
......@@ -133,17 +130,18 @@ Expect $LINENO 0 "PASS" "" --help=false
Expect $LINENO 1 "/gflags_reporting.cc" "" -helpfull
# --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
Expect $LINENO 1 "tldflag1" "/google.cc" --helpshort
Expect $LINENO 1 "tldflag2" "/google.cc" --helpshort
# --helpshort should work if the main source file is suffixed with [_-]main
ExpectExe "$EXE2" $LINENO 1 "/gflags_unittest-main.cc" "/gflags_reporting.cc" \
--helpshort
ExpectExe "$EXE3" $LINENO 1 "/gflags_unittest_main.cc" "/gflags_reporting.cc" \
--helpshort
ExpectExe "$EXE2" $LINENO 1 "/gflags_unittest-main.cc" \
"/gflags_reporting.cc" --helpshort
ExpectExe "$EXE3" $LINENO 1 "/gflags_unittest_main.cc" \
"/gflags_reporting.cc" --helpshort
# --helpon needs an argument
Expect $LINENO 1 \
......@@ -151,20 +149,22 @@ Expect $LINENO 1 \
"" --helpon
# --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
Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" --helpon gflags
Expect $LINENO 1 "/gflags.cc" "/gflags_unittest.cc" \
--helpon gflags
# test another argument
Expect $LINENO 1 "/gflags_unittest.cc" "/gflags.cc" \
--helpon gflags_unittest
--helpon=gflags_unittest
# helpmatch is like helpon but takes substrings
Expect $LINENO 1 "/gflags_reporting.cc" "/gflags_unittest.cc" \
-helpmatch reporting
Expect $LINENO 1 "/gflags_unittest.cc" "/gflags.cc" \
-helpmatch=unittest
Expect $LINENO 1 "/gflags_reporting.cc" \
"/gflags_unittest.cc" -helpmatch reporting
Expect $LINENO 1 "/gflags_unittest.cc" \
"/gflags.cc" -helpmatch=unittest
# if no flags are found with helpmatch or helpon, suggest --help
Expect $LINENO 1 "No modules matched" "/gflags_unittest.cc" \
......@@ -202,8 +202,10 @@ Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.2"
Expect $LINENO 0 "PASS" "" --flagfile="$TMPDIR/flagfile.3"
# 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" --tryfromenv=version
Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
--fromenv=version
Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
--tryfromenv=version
Expect $LINENO 0 "PASS" "" --fromenv=help
Expect $LINENO 0 "PASS" "" --tryfromenv=help
Expect $LINENO 1 "helpfull not found in environment" "" --fromenv=helpfull
......@@ -221,10 +223,11 @@ Expect $LINENO 0 "gflags_unittest" "gflags_unittest.cc" \
# Make sure -- by itself stops argv processing
Expect $LINENO 0 "PASS" "" -- --help
# 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
# TODO(wojtekm) And if locking in validators fails.
# TODO(user) And if locking in validators fails.
# Expect $LINENO 0 "PASS" "" --deadlock_if_cant_lock
echo "PASS"
......
......@@ -28,7 +28,6 @@
// 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.
// You should assume the locks are *not* re-entrant.
......@@ -117,7 +116,12 @@
#if defined(NO_THREADS)
typedef int MutexType; // to keep a lock-count
#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
// We need Windows NT or later for TryEnterCriticalSection(). If you
// don't need that functionality, you can remove these _WIN32_WINNT
......@@ -134,7 +138,10 @@
// *does* cause problems for FreeBSD, or MacOSX, but isn't needed
// for locking there.)
# 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
# include <pthread.h>
typedef pthread_rwlock_t MutexType;
......
This diff is collapsed.
This diff is collapsed.
......@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// ---
// Author: Dave Nicponski
//
// Implement helpful bash-style command line flag completions
//
......@@ -88,8 +88,8 @@
// file would be (your path to gflags_completions.sh file may differ):
/*
$ complete -o bashdefault -o default -o nospace -C \
'/usr/local/bin/gflags_completions.sh --tab_completion_columns $COLUMNS' \
$ complete -o bashdefault -o default -o nospace -C \
'/home/build/eng/bash/bash_completions.sh --tab_completion_columns $COLUMNS' \
time env binary_name another_binary [...]
*/
......@@ -109,22 +109,27 @@ $ complete -o bashdefault -o default -o nospace -C \
// produce the expected completion output.
#ifndef GOOGLE_GFLAGS_COMPLETIONS_H_
#define GOOGLE_GFLAGS_COMPLETIONS_H_
#ifndef BASE_COMMANDLINEFLAGS_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
# define GFLAGS_DLL_DECL /**/
# endif
#endif
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.
//
// Redistribution and use in source and binary forms, with or without
......@@ -28,7 +28,7 @@
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// ---
// Author: Ray Sidney
//
// Revamped and reorganized by Craig Silverstein
//
// This is the file that should be included by any file which declares
......@@ -38,36 +38,17 @@
#define BASE_COMMANDLINEFLAGS_DECLARE_H_
#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
#include <stdint.h> // the normal place uint16_t is defined
#include <stdint.h> // the normal place uint16_t is defined
#endif
#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
#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
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
typedef int32_t int32;
typedef uint32_t uint32;
......@@ -78,7 +59,7 @@ typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif 1 // the windows (vc7) format
#elif 1 // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
......@@ -86,6 +67,39 @@ typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#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;
namespace fL##shorttype { extern GFLAGS_DLL_DECLARE_FLAG type FLAGS_##name; } \
using fL##shorttype::FLAGS_##name
#define DECLARE_bool(name) DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(name) DECLARE_VARIABLE(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_bool(name) \
DECLARE_VARIABLE(bool, B, name)
#define DECLARE_int32(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) \
namespace fLS { \
using ::fLS::clstring; \
......
......@@ -37,20 +37,49 @@
#include <config.h>
#include <string.h> // for strlen(), memset(), memcmp()
#include <stdlib.h> // for _putenv, etc.
#include <assert.h>
#include <stdarg.h> // for va_list, va_start, va_end
#include <windows.h>
#include "port.h"
#ifndef HAVE_SNPRINTF
int snprintf(char *str, size_t size, const char *format, ...) {
// These call the windows _vsnprintf, but always NUL-terminate.
#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?
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_start(ap, format);
const int r = _vsnprintf(str, size-1, format, ap);
r = vsnprintf(str, size, format, ap);
va_end(ap);
str[size-1] = '\0';
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 @@
#include <windows.h>
#include <direct.h> /* for mkdir */
#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
// ----------------------------------- STRING ROUTINES
// We can't just use _snprintf as a drop-in-replacement, because it
// doesn't always NUL-terminate. :-(
/* 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
* name vsnprintf, since windows defines that (but not snprintf (!)).
*/
#if !defined(__MINGW32__) && !defined(__MINGW64__) /* mingw already defines */
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
......
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