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,