Wed Mar 28 12:15:56 2007 Google Inc. <opensource@google.com>
* google-gflags: version 0.3
* python portability fix: use popen instead of subprocess (csilvers)
* Add is_default to CommandLineFlagInfo (pchien)
* Make docs a bit prettier (csilvers)
* Actually include the python files in the distribution! :-/ (csilvers)
git-svn-id: https://gflags.googlecode.com/svn/trunk@11 6586e3c6-dcc4-952a-343f-ff74eb82781d
diff --git a/ChangeLog b/ChangeLog
index e5f126b..1e0439e 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,3 +12,11 @@
* google-gflags: version 0.2
* added support for python commandlineflags, as well as c++
* gflags2man, a script to turn flags into a man page (dchristian)
+
+Wed Mar 28 12:15:56 2007 Google Inc. <opensource@google.com>
+
+ * google-gflags: version 0.3
+ * python portability fix: use popen instead of subprocess (csilvers)
+ * Add is_default to CommandLineFlagInfo (pchien)
+ * Make docs a bit prettier (csilvers)
+ * Actually include the python files in the distribution! :-/ (csilvers)
diff --git a/Makefile.am b/Makefile.am
index c2b4287..d37f565 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -58,6 +58,13 @@
gflags_unittest_sh: gflags_unittest
$(top_srcdir)/src/gflags_unittest.sh $(PWD)/$<
+# These aren't part of the c++ source, but we want them to be distributed
+PYTHON = python/setup.py \
+ python/gflags.py \
+ python/gflags2man.py \
+ python/gflags_unittest.py
+
+
## ^^^^ END OF RULES TO MAKE THE LIBRARIES, BINARIES, AND UNITTESTS
@@ -74,4 +81,4 @@
libtool: $(LIBTOOL_DEPS)
$(SHELL) ./config.status --recheck
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
- libtool $(SCRIPTS)
+ libtool $(SCRIPTS) $(PYTHON)
diff --git a/Makefile.in b/Makefile.in
index 815511d..3ee7c0a 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -260,8 +260,15 @@
gflags_unittest_CXXFLAGS = $(PTHREAD_CFLAGS)
gflags_unittest_LDFLAGS = $(PTHREAD_CFLAGS)
gflags_unittest_LDADD = libgflags.la $(PTHREAD_LIBS)
+
+# These aren't part of the c++ source, but we want them to be distributed
+PYTHON = python/setup.py \
+ python/gflags.py \
+ python/gflags2man.py \
+ python/gflags_unittest.py
+
EXTRA_DIST = packages/rpm.sh packages/rpm/rpm.spec packages/deb.sh packages/deb \
- libtool $(SCRIPTS)
+ libtool $(SCRIPTS) $(PYTHON)
all: all-am
@@ -586,7 +593,7 @@
distdir: $(DISTFILES)
$(am__remove_distdir)
mkdir $(distdir)
- $(mkdir_p) $(distdir)/doc $(distdir)/packages $(distdir)/packages/rpm $(distdir)/src $(distdir)/src/google
+ $(mkdir_p) $(distdir)/doc $(distdir)/packages $(distdir)/packages/rpm $(distdir)/python $(distdir)/src $(distdir)/src/google
@srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
list='$(DISTFILES)'; for file in $$list; do \
diff --git a/aclocal.m4 b/aclocal.m4
index 0155b92..14be9c1 100644
--- a/aclocal.m4
+++ b/aclocal.m4
@@ -6741,12 +6741,10 @@
AC_MSG_CHECKING(for __attribute__)
AC_CACHE_VAL(ac_cv___attribute__, [
AC_TRY_COMPILE(
- [#include <stdlib.h>],
- [static void foo(void) __attribute__ ((unused));
- static void
- foo(void) {
- exit(1);
- }],
+ [#include <stdlib.h>
+ static void foo(void) __attribute__ ((unused));
+ void foo(void) { exit(1); }],
+ [],
ac_cv___attribute__=yes,
ac_cv___attribute__=no
)])
diff --git a/configure b/configure
index 590bdff..4aa45e0 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for gflags 0.2.
+# Generated by GNU Autoconf 2.59 for gflags 0.3.
#
# Report bugs to <opensource@google.com>.
#
@@ -423,8 +423,8 @@
# Identity of this package.
PACKAGE_NAME='gflags'
PACKAGE_TARNAME='gflags'
-PACKAGE_VERSION='0.2'
-PACKAGE_STRING='gflags 0.2'
+PACKAGE_VERSION='0.3'
+PACKAGE_STRING='gflags 0.3'
PACKAGE_BUGREPORT='opensource@google.com'
ac_unique_file="README"
@@ -954,7 +954,7 @@
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures gflags 0.2 to adapt to many kinds of systems.
+\`configure' configures gflags 0.3 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1020,7 +1020,7 @@
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of gflags 0.2:";;
+ short | recursive ) echo "Configuration of gflags 0.3:";;
esac
cat <<\_ACEOF
@@ -1163,7 +1163,7 @@
test -n "$ac_init_help" && exit 0
if $ac_init_version; then
cat <<\_ACEOF
-gflags configure 0.2
+gflags configure 0.3
generated by GNU Autoconf 2.59
Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1177,7 +1177,7 @@
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by gflags $as_me 0.2, which was
+It was created by gflags $as_me 0.3, which was
generated by GNU Autoconf 2.59. Invocation command line was
$ $0 $@
@@ -1823,7 +1823,7 @@
# Define the identity of the package.
PACKAGE='gflags'
- VERSION='0.2'
+ VERSION='0.3'
cat >>confdefs.h <<_ACEOF
@@ -19798,14 +19798,12 @@
cat >>conftest.$ac_ext <<_ACEOF
/* end confdefs.h. */
#include <stdlib.h>
+ static void foo(void) __attribute__ ((unused));
+ void foo(void) { exit(1); }
int
main ()
{
-static void foo(void) __attribute__ ((unused));
- static void
- foo(void) {
- exit(1);
- }
+
;
return 0;
}
@@ -21158,7 +21156,7 @@
} >&5
cat >&5 <<_CSEOF
-This file was extended by gflags $as_me 0.2, which was
+This file was extended by gflags $as_me 0.3, which was
generated by GNU Autoconf 2.59. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -21221,7 +21219,7 @@
cat >>$CONFIG_STATUS <<_ACEOF
ac_cs_version="\\
-gflags config.status 0.2
+gflags config.status 0.3
configured by $0, generated by GNU Autoconf 2.59,
with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
diff --git a/configure.ac b/configure.ac
index 98a07c2..d78df0c 100644
--- a/configure.ac
+++ b/configure.ac
@@ -10,7 +10,7 @@
# make sure we're interpreted by some minimal autoconf
AC_PREREQ(2.57)
-AC_INIT(gflags, 0.2, opensource@google.com)
+AC_INIT(gflags, 0.3, opensource@google.com)
# The argument here is just something that should be in the current directory
# (for sanity checking)
AC_CONFIG_SRCDIR(README)
diff --git a/doc/designstyle.css b/doc/designstyle.css
new file mode 100644
index 0000000..f5d1ec2
--- /dev/null
+++ b/doc/designstyle.css
@@ -0,0 +1,115 @@
+body {
+ background-color: #ffffff;
+ color: black;
+ margin-right: 1in;
+ margin-left: 1in;
+}
+
+
+h1, h2, h3, h4, h5, h6 {
+ color: #3366ff;
+ font-family: sans-serif;
+}
+@media print {
+ /* Darker version for printing */
+ h1, h2, h3, h4, h5, h6 {
+ color: #000080;
+ font-family: helvetica, sans-serif;
+ }
+}
+
+h1 {
+ text-align: center;
+ font-size: 18pt;
+}
+h2 {
+ margin-left: -0.5in;
+}
+h3 {
+ margin-left: -0.25in;
+}
+h4 {
+ margin-left: -0.125in;
+}
+hr {
+ margin-left: -1in;
+}
+
+/* Definition lists: definition term bold */
+dt {
+ font-weight: bold;
+}
+
+address {
+ text-align: right;
+}
+/* Use the <code> tag for bits of code and <var> for variables and objects. */
+code,pre,samp,var {
+ color: #006000;
+}
+/* Use the <file> tag for file and directory paths and names. */
+file {
+ color: #905050;
+ font-family: monospace;
+}
+/* Use the <kbd> tag for stuff the user should type. */
+kbd {
+ color: #600000;
+}
+div.note p {
+ float: right;
+ width: 3in;
+ margin-right: 0%;
+ padding: 1px;
+ border: 2px solid #6060a0;
+ background-color: #fffff0;
+}
+
+UL.nobullets {
+ list-style-type: none;
+ list-style-image: none;
+ margin-left: -1em;
+}
+
+/*
+body:after {
+ content: "Google Confidential";
+}
+*/
+
+/* pretty printing styles. See prettify.js */
+.str { color: #080; }
+.kwd { color: #008; }
+.com { color: #800; }
+.typ { color: #606; }
+.lit { color: #066; }
+.pun { color: #660; }
+.pln { color: #000; }
+.tag { color: #008; }
+.atn { color: #606; }
+.atv { color: #080; }
+pre.prettyprint { padding: 2px; border: 1px solid #888; }
+
+.embsrc { background: #eee; }
+
+@media print {
+ .str { color: #060; }
+ .kwd { color: #006; font-weight: bold; }
+ .com { color: #600; font-style: italic; }
+ .typ { color: #404; font-weight: bold; }
+ .lit { color: #044; }
+ .pun { color: #440; }
+ .pln { color: #000; }
+ .tag { color: #006; font-weight: bold; }
+ .atn { color: #404; }
+ .atv { color: #060; }
+}
+
+/* Table Column Headers */
+.hdr {
+ color: #006;
+ font-weight: bold;
+ background-color: #dddddd; }
+.hdr2 {
+ color: #006;
+ background-color: #eeeeee; }
\ No newline at end of file
diff --git a/packages/deb/libgoogle-gflags-dev.dirs b/packages/deb/libgoogle-gflags-dev.dirs
new file mode 100644
index 0000000..9fdbd88
--- /dev/null
+++ b/packages/deb/libgoogle-gflags-dev.dirs
@@ -0,0 +1,3 @@
+usr/lib
+usr/include
+usr/include/google
diff --git a/packages/deb/libgoogle-gflags-dev.install b/packages/deb/libgoogle-gflags-dev.install
new file mode 100644
index 0000000..d81ff20
--- /dev/null
+++ b/packages/deb/libgoogle-gflags-dev.install
@@ -0,0 +1,8 @@
+usr/include/google/*
+usr/lib/lib*.so
+usr/lib/lib*.a
+usr/lib/*.la
+debian/tmp/usr/include/google/*
+debian/tmp/usr/lib/lib*.so
+debian/tmp/usr/lib/lib*.a
+debian/tmp/usr/lib/*.la
diff --git a/packages/deb/libgoogle-gflags0.dirs b/packages/deb/libgoogle-gflags0.dirs
new file mode 100644
index 0000000..6845771
--- /dev/null
+++ b/packages/deb/libgoogle-gflags0.dirs
@@ -0,0 +1 @@
+usr/lib
diff --git a/packages/deb/libgoogle-gflags0.install b/packages/deb/libgoogle-gflags0.install
new file mode 100644
index 0000000..704ea87
--- /dev/null
+++ b/packages/deb/libgoogle-gflags0.install
@@ -0,0 +1,2 @@
+usr/lib/lib*.so.*
+debian/tmp/usr/lib/lib*.so.*
diff --git a/python/gflags2man.py b/python/gflags2man.py
index 4edac1c..f346564 100755
--- a/python/gflags2man.py
+++ b/python/gflags2man.py
@@ -52,7 +52,6 @@
import sys
import stat
import time
-import subprocess
import gflags
@@ -189,29 +188,18 @@
logging.info('Running: %s %s </dev/null 2>&1'
% (self.executable, FLAGS.help_flag))
- # --help output is often routed to stderr, so we re-direct that to
- # stdout. Re-direct stdin to /dev/null to encourage programs that
+ # --help output is often routed to stderr, so we combine with stdout.
+ # Re-direct stdin to /dev/null to encourage programs that
# don't understand --help to exit.
- try:
- runstate = subprocess.Popen(
- [self.executable, FLAGS.help_flag],
- stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
- stdin=open('/dev/null', 'r'))
- except OSError, msg:
- logging.error('Error executing "%s": %s' % (self.name, msg))
- return 0
-
- # read output progressively so the pipe doesn't fill up (fileutil).
- self.output = runstate.stdout.readlines()
- status = runstate.wait()
- logging.debug('Program exited with %s' % status)
- output = runstate.communicate()[0]
- if output:
- self.output = output.splitlines()
+ (child_stdin, child_stdout_and_stderr) = os.popen4(
+ [self.executable, FLAGS.help_flag])
+ child_stdin.close() # '</dev/null'
+ self.output = child_stdout_and_stderr.readlines()
+ child_stdout_and_stderr.close()
if len(self.output) < _MIN_VALID_USAGE_MSG:
- logging.error(
- 'Error: "%s %s" returned %d and only %d lines: %s'
- % (self.name, FLAGS.help_flag, status, len(self.output), output))
+ logging.error('Error: "%s %s" returned only %d lines: %s'
+ % (self.name, FLAGS.help_flag,
+ len(self.output), self.output))
return 0
return 1
diff --git a/python/setup.py b/python/setup.py
index c139338..73350a8 100755
--- a/python/setup.py
+++ b/python/setup.py
@@ -32,7 +32,7 @@
from distutils.core import setup
setup(name='gflags',
- version='0.2',
+ version='0.3',
description='Google Commandline Flags Module',
license='BSD',
author='Google Inc.',
diff --git a/src/config.h.in b/src/config.h.in
new file mode 100644
index 0000000..16514b0
--- /dev/null
+++ b/src/config.h.in
@@ -0,0 +1,80 @@
+/* src/config.h.in. Generated from configure.ac by autoheader. */
+
+/* Namespace for Google classes */
+#undef GOOGLE_NAMESPACE
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* define if the compiler implements namespaces */
+#undef HAVE_NAMESPACES
+
+/* Define if you have POSIX threads libraries and header files. */
+#undef HAVE_PTHREAD
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* define if your compiler has __attribute__ */
+#undef HAVE___ATTRIBUTE__
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to necessary symbol if this constant uses a non-standard name on
+ your system. */
+#undef PTHREAD_CREATE_JOINABLE
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* the namespace where STL code like vector<> is defined */
+#undef STL_NAMESPACE
+
+/* Version number of package */
+#undef VERSION
+
+/* Stops putting the code inside the Google namespace */
+#undef _END_GOOGLE_NAMESPACE_
+
+/* Puts following code inside the Google namespace */
+#undef _START_GOOGLE_NAMESPACE_
diff --git a/src/gflags.cc b/src/gflags.cc
index b8cd900..02c6ffe 100644
--- a/src/gflags.cc
+++ b/src/gflags.cc
@@ -316,7 +316,7 @@
string default_value() const { return defvalue_->ToString(); }
const char* type_name() const { return defvalue_->TypeName(); }
- void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result) const;
+ void FillCommandLineFlagInfo(struct CommandLineFlagInfo* result);
private:
friend class FlagRegistry; // for SetFlagLocked()
@@ -386,13 +386,15 @@
}
void CommandLineFlag::FillCommandLineFlagInfo(
- CommandLineFlagInfo* result) const {
+ CommandLineFlagInfo* result) {
result->name = name();
result->type = type_name();
result->description = help();
result->current_value = current_value();
result->default_value = default_value();
result->filename = CleanFileName();
+ UpdateModifiedBit();
+ result->is_default = !modified_;
}
void CommandLineFlag::UpdateModifiedBit() {
@@ -1141,6 +1143,7 @@
// --------------------------------------------------------------------
// GetCommandLineOption()
// GetCommandLineFlagInfo()
+// GetCommandLineFlagInfoOrDie()
// SetCommandLineOption()
// SetCommandLineOptionWithMode()
// The programmatic way to set a flag's value, using a string
@@ -1196,6 +1199,15 @@
}
}
+CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name) {
+ CommandLineFlagInfo info;
+ if (!GetCommandLineFlagInfo(name, &info)) {
+ fprintf(stderr, "FATAL ERROR: flag name '%s' doesn't exit", name);
+ commandlineflags_exitfunc(1); // almost certainly exit()
+ }
+ return info;
+}
+
string SetCommandLineOptionWithMode(const char* name, const char* value,
FlagSettingMode set_mode) {
string result;
diff --git a/src/gflags_unittest.cc b/src/gflags_unittest.cc
index b614919..495898c 100644
--- a/src/gflags_unittest.cc
+++ b/src/gflags_unittest.cc
@@ -860,6 +860,45 @@
EXPECT_EQ(false, r);
}
+TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndIsDefault) {
+ CommandLineFlagInfo info;
+ info = GetCommandLineFlagInfoOrDie("test_int32");
+ EXPECT_EQ("test_int32", info.name);
+ EXPECT_EQ("int32", info.type);
+ EXPECT_EQ("", info.description);
+ EXPECT_EQ("-1", info.default_value);
+ EXPECT_EQ(true, info.is_default);
+ info = GetCommandLineFlagInfoOrDie("test_bool");
+ EXPECT_EQ("test_bool", info.name);
+ EXPECT_EQ("bool", info.type);
+ EXPECT_EQ("tests bool-ness", info.description);
+ EXPECT_EQ("false", info.default_value);
+ EXPECT_EQ(true, info.is_default);
+}
+
+TEST(GetCommandLineFlagInfoOrDieTest, FlagExistsAndWasAssigned) {
+ FLAGS_test_int32 = 400;
+ CommandLineFlagInfo info;
+ info = GetCommandLineFlagInfoOrDie("test_int32");
+ EXPECT_EQ("test_int32", info.name);
+ EXPECT_EQ("int32", info.type);
+ EXPECT_EQ("", info.description);
+ EXPECT_EQ("-1", info.default_value);
+ EXPECT_EQ(false, info.is_default);
+ FLAGS_test_bool = true;
+ info = GetCommandLineFlagInfoOrDie("test_bool");
+ EXPECT_EQ("test_bool", info.name);
+ EXPECT_EQ("bool", info.type);
+ EXPECT_EQ("tests bool-ness", info.description);
+ EXPECT_EQ("false", info.default_value);
+ EXPECT_EQ(false, info.is_default);
+}
+
+TEST(GetCommandLineFlagInfoOrDieTest, FlagDoesNotExist) {
+ EXPECT_DEATH(GetCommandLineFlagInfoOrDie("test_int3210"),
+ ".*: flag test_int3210 does not exist");
+}
+
// These are lightly tested because they're deprecated. Basically,
// the tests are meant to cover how existing users use these functions,
diff --git a/src/google/gflags.h.in b/src/google/gflags.h.in
index 13043f5..eae1fa5 100644
--- a/src/google/gflags.h.in
+++ b/src/google/gflags.h.in
@@ -112,6 +112,7 @@
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 is_default; // true if the flag has default value
};
extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
@@ -140,11 +141,19 @@
// OUTPUT is set to the flag's value, or unchanged if we return false.
extern bool GetCommandLineOption(const char* name, std::string* OUTPUT,
bool *is_default_value = NULL);
+
// 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);
+// Return the CommandLineFlagInfo of the flagname.
+// assertion failure if the flagname was not found.
+//
+// Example to check if a flag has default value:
+// if (GetCommandLineFlagInfoOrDie("foo").is_default)
+extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+
enum FlagSettingMode {
// update the flag's value (can call this multiple times).
SET_FLAGS_VALUE,