Libmv: Update to latest upstream version
authorSergey Sharybin <sergey.vfx@gmail.com>
Wed, 31 Dec 2014 10:55:00 +0000 (15:55 +0500)
committerSergey Sharybin <sergey.vfx@gmail.com>
Wed, 31 Dec 2014 11:02:04 +0000 (16:02 +0500)
Main purpose of this is to bring new gflags library which is more likely
to have a fix for undefined order of static variables initialization and
also to bring new glog where some compilation error are fixed (which are
only visible with more strict checks with clang and c++11 enabled).

28 files changed:
extern/libmv/CMakeLists.txt
extern/libmv/ChangeLog
extern/libmv/SConscript
extern/libmv/bundle.sh
extern/libmv/files.txt
extern/libmv/intern/logging.cc
extern/libmv/third_party/gflags/AUTHORS.txt [moved from extern/libmv/third_party/gflags/AUTHORS with 100% similarity]
extern/libmv/third_party/gflags/COPYING.txt [moved from extern/libmv/third_party/gflags/COPYING with 100% similarity]
extern/libmv/third_party/gflags/ChangeLog [deleted file]
extern/libmv/third_party/gflags/ChangeLog.txt [new file with mode: 0644]
extern/libmv/third_party/gflags/NEWS.txt [moved from extern/libmv/third_party/gflags/NEWS with 61% similarity]
extern/libmv/third_party/gflags/README.libmv
extern/libmv/third_party/gflags/config.h
extern/libmv/third_party/gflags/gflags.cc
extern/libmv/third_party/gflags/gflags/gflags.h
extern/libmv/third_party/gflags/gflags/gflags_completions.h
extern/libmv/third_party/gflags/gflags/gflags_declare.h
extern/libmv/third_party/gflags/gflags_completions.cc
extern/libmv/third_party/gflags/gflags_reporting.cc
extern/libmv/third_party/gflags/mutex.h
extern/libmv/third_party/gflags/util.h
extern/libmv/third_party/glog/README.libmv
extern/libmv/third_party/glog/src/demangle.cc
extern/libmv/third_party/glog/src/logging.cc
extern/libmv/third_party/glog/src/symbolize.cc
extern/libmv/third_party/glog/src/symbolize.h
intern/cycles/blender/blender_logging.cpp
tests/gtests/testing/testing_main.cc

index 49f77615bee03327827786274288dd739e36697c..4528c0b4dd2f3ba3e8b7074430d08f34e38d3614 100644 (file)
@@ -40,14 +40,14 @@ set(SRC
 if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
        list(APPEND INC
                third_party/gflags
+               third_party/gflags/gflags
                third_party/glog/src
                third_party/ceres/include
                third_party/ceres/config
                ../../intern/guardedalloc
        )
 
-       list(APPEND
-               INC_SYS
+       list(APPEND INC_SYS
                ../Eigen3
                ${PNG_INCLUDE_DIRS}
                ${ZLIB_INCLUDE_DIRS}
index 5c2129b6b1a6ceae37a9db640dff43127db86d14..0bb340b2491396fbce1b8fa9db2fd3748e05fd28 100644 (file)
@@ -1,3 +1,42 @@
+commit 7d6020d2ec42c6cb2749bc891186b4880d26d40b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Wed Dec 31 15:32:07 2014 +0500
+
+    Update GLog to latest upstream revision 143
+    
+    Mainly to solve compilation error with demangle.cc.
+
+commit 5dc746700eaf85cb674f0fb73ff3c1b49a7f6315
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Fri Dec 12 14:59:55 2014 +0500
+
+    Update GFlags to latest release 2.1.1
+    
+    Main purpose of this (andsome of upcoming) update is to check if the
+    upstream sources are useable without any modifications for us. And if
+    not, then we'll need to consider moving some changes into upstream.
+    
+    This commit contains an one-to-one copy of the upstream GFlags library
+    and also changes namespace usage since it's changed in the upstream.
+
+commit 6fe6d75f7e90e161b44643b953f058a3829a5247
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Sat Nov 1 02:53:36 2014 +0500
+
+    Libmv: Code cleanup, mixed class/struct in declaration/definition
+
+commit d2a5f7953812d2d09765431b59c6c4ac72faf35b
+Author: Sergey Sharybin <sergey.vfx@gmail.com>
+Date:   Thu Oct 30 23:13:53 2014 +0500
+
+    Libmv: Support disabled color channels in tracking settings
+    
+    This was never ported to a new tracking pipeline and now it's done using
+    FrameAccessor::Transform routines. Quite striaghtforward, but i've changed
+    order of grayscale conversion in blender side with call of transform callback.
+    
+    This way it's much easier to perform rescaling in libmv side.
+
 commit d976e034cdf74b34860e0632d7b29713f47c5756
 Author: Keir Mierle <mierle@gmail.com>
 Date:   Sat Aug 23 00:38:01 2014 -0700
@@ -666,37 +705,3 @@ Author: Sergey Sharybin <sergey.vfx@gmail.com>
 Date:   Tue Feb 18 19:38:22 2014 +0600
 
     Remove .orig file which was added by accident
-
-commit 62597e3cf0f266a2fefec415c89759e502793e06
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date:   Thu Jan 2 16:02:08 2014 +0600
-
-    Upgrade glog to latest svn r139
-    
-    The intention of this upgrade is to get rid of custom patches
-    we've been having to support compilation on different platforms
-    and compilers.
-
-commit 2452d5d42b390c7ab853e6fe60e58bdd7a01a004
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date:   Tue Feb 18 18:46:08 2014 +0600
-
-    Tweak Ceres CMake to detect uninstall target properly on Windows
-
-commit 98a281d58ce2301f3dd239a97a448e53f48d0258
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date:   Fri Feb 14 00:36:44 2014 +0600
-
-    Fix order of third party libs compilation and options used by them
-    
-    WITH_FAST_DETECTOR was defined too late and third_party folder
-    didn't see this option.
-
-commit 4962bccd643ec0f2aed3035170d5f20e8f6efc85
-Author: Sergey Sharybin <sergey.vfx@gmail.com>
-Date:   Thu Feb 13 23:55:03 2014 +0600
-
-    Disable Ceres unit tests and examples by default
-    
-    Actually we're to switch to external Ceres rather than
-    bundled one, would make life much easier actually.
index 6d41727451b38bf213eaea204ddfd2c28e9b08ac..6211bf665128bd146433dcddfbc77a00a329df5b 100644 (file)
@@ -17,7 +17,7 @@ if env['WITH_BF_LIBMV'] or (env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGIN
     defs.append('WITH_LIBMV_GUARDED_ALLOC')
     defs.append('LIBMV_NO_FAST_DETECTOR')
 
-    incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
+    incs += ' ../Eigen3 third_party/gflags third_party/gflags/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
     incs += ' ' + env['BF_PNG_INC']
     incs += ' ' + env['BF_ZLIB_INC']
 
index 002e3816c7191f1509818a083c461e1267d92237..f8aaaa966f40e9dd541b9c96bc63d31fe1c44cb9 100755 (executable)
@@ -133,6 +133,7 @@ set(SRC
 if(WITH_LIBMV OR WITH_GTESTS OR (WITH_CYCLES AND WITH_CYCLES_LOGGING))
        list(APPEND INC
                third_party/gflags
+               third_party/gflags/gflags
                third_party/glog/src
                third_party/ceres/include
                third_party/ceres/config
@@ -294,7 +295,7 @@ if env['WITH_BF_LIBMV'] or (env['WITH_BF_CYCLES'] and env['WITH_BF_CYCLES_LOGGIN
     defs.append('WITH_LIBMV_GUARDED_ALLOC')
     defs.append('LIBMV_NO_FAST_DETECTOR')
 
-    incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
+    incs += ' ../Eigen3 third_party/gflags third_party/gflags/gflags third_party/glog/src third_party/ceres/include third_party/ceres/config ../../intern/guardedalloc'
     incs += ' ' + env['BF_PNG_INC']
     incs += ' ' + env['BF_ZLIB_INC']
 
index a206ffe1edd83be9b713d1edfe96c4c0dbcb6d1a..91a529beb5a0614b34961011bce2d4b1c78582bf 100644 (file)
@@ -133,10 +133,10 @@ libmv/tracking/track_region.cc
 libmv/tracking/track_region.h
 libmv/tracking/trklt_region_tracker.cc
 libmv/tracking/trklt_region_tracker.h
-third_party/gflags/AUTHORS
-third_party/gflags/ChangeLog
+third_party/gflags/AUTHORS.txt
+third_party/gflags/ChangeLog.txt
 third_party/gflags/config.h
-third_party/gflags/COPYING
+third_party/gflags/COPYING.txt
 third_party/gflags/gflags.cc
 third_party/gflags/gflags_completions.cc
 third_party/gflags/gflags/gflags_completions.h
@@ -144,7 +144,7 @@ third_party/gflags/gflags/gflags_declare.h
 third_party/gflags/gflags/gflags.h
 third_party/gflags/gflags_reporting.cc
 third_party/gflags/mutex.h
-third_party/gflags/NEWS
+third_party/gflags/NEWS.txt
 third_party/gflags/README.libmv
 third_party/gflags/util.h
 third_party/glog/AUTHORS
index 4ab2d91c8b4423b78a4e1d8ae8ed97b5bc78e6ed..77b56ef4df3ec674eca98d1035ac1922c22fe912 100644 (file)
@@ -35,21 +35,21 @@ void libmv_initLogging(const char* argv0) {
            google::GLOG_FATAL);
 
   google::InitGoogleLogging(argv0);
-  google::SetCommandLineOption("logtostderr", "1");
-  google::SetCommandLineOption("v", "0");
-  google::SetCommandLineOption("stderrthreshold", severity_fatal);
-  google::SetCommandLineOption("minloglevel", severity_fatal);
+  gflags::SetCommandLineOption("logtostderr", "1");
+  gflags::SetCommandLineOption("v", "0");
+  gflags::SetCommandLineOption("stderrthreshold", severity_fatal);
+  gflags::SetCommandLineOption("minloglevel", severity_fatal);
 }
 
 void libmv_startDebugLogging(void) {
-  google::SetCommandLineOption("logtostderr", "1");
-  google::SetCommandLineOption("v", "2");
-  google::SetCommandLineOption("stderrthreshold", "1");
-  google::SetCommandLineOption("minloglevel", "0");
+  gflags::SetCommandLineOption("logtostderr", "1");
+  gflags::SetCommandLineOption("v", "2");
+  gflags::SetCommandLineOption("stderrthreshold", "1");
+  gflags::SetCommandLineOption("minloglevel", "0");
 }
 
 void libmv_setLoggingVerbosity(int verbosity) {
   char val[10];
   snprintf(val, sizeof(val), "%d", verbosity);
-  google::SetCommandLineOption("v", val);
+  gflags::SetCommandLineOption("v", val);
 }
diff --git a/extern/libmv/third_party/gflags/ChangeLog b/extern/libmv/third_party/gflags/ChangeLog
deleted file mode 100644 (file)
index f9ef935..0000000
+++ /dev/null
@@ -1,195 +0,0 @@
-Wed Jan 25 15:09:14 2012  Google Inc. <google-gflags@googlegroups.com>
-
-       * gflags: version 2.0
-       * Changed the 'official' gflags email in setup.py/etc
-       * Renamed google-gflags.sln to gflags.sln
-       * Changed copyright text to reflect Google's relinquished ownership
-
-Tue Dec 20 19:48:57 2011  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.7
-       * Add CommandLineFlagInfo::flag_ptr pointing to current storage (musji)
-       * PORTING: flush after writing to stderr, needed on cygwin
-       * PORTING: Clean up the GFLAGS_DLL_DECL stuff better
-       * Fix a bug in StringPrintf() that affected large strings (csilvers)
-       * Die at configure-time when g++ isn't installed
-
-Fri Jul 29 19:05:21 2011  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.6
-       * BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
-       * Fix definition of clstring (jyrki)
-       * Split up flag declares into its own file (jyrki)
-       * Add --version support (csilvers)
-       * Update the README for gflags with static libs
-       * Update acx_pthread.m4 for nostdlib
-       * Change ReparseCommandLineFlags to return void (csilvers)
-       * Some doc typofixes and example augmentation (various)
-
-Mon Jan 24 16:11:35 2011  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.5
-       * Better reporting of current vs default value (handler)
-       * Add API for cleaning up of memory at program-exit (jmarantz)
-       * Fix macros to work inside namespaces (csilvers)
-       * Use our own string typedef in case string is redefined (csilvers)
-       * Updated to autoconf 2.65
-
-Wed Oct 13 17:40:12 2010  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.4
-       * Add a check to prevent passing 0 to DEFINE_string (jorg)
-       * Reduce compile (.o) size (jyrki)
-       * Some small changes to quiet debug compiles (alexk)
-       * PORTING: better support static linking on windows (csilvers)
-       * DOCUMENTATION: change default values, use validators, etc.
-       * Update the NEWS file to be non-empty
-       * Add pkg-config (.pc) files for libgflags and libgflags_nothreads
-
-Mon Jan  4 18:09:30 2010  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.3
-       * PORTABILITY: can now build and run tests under MSVC (csilvers)
-       * Remove the python gflags code, which is now its own package (tansell)
-       * Clarify that "last flag wins" in the docs (csilvers)
-       * Comment danger of using GetAllFlags in validators (wojtekm)
-       * PORTABILITY: Some fixes necessary for c++0x (mboerger)
-       * Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
-       * INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
-
-Thu Sep 10 12:53:04 2009  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.2
-       * PORTABILITY: can now build and run tests under mingw (csilvers)
-       * Using a string arg for a bool flag is a compile-time error (rbayardo)
-       * Add --helpxml to gflags.py (salcianu)
-       * Protect against a hypothetical global d'tor mutex problem (csilvers)
-       * BUGFIX: can now define a flag after 'using namespace google' (hamaji)
-
-Tue Apr 14 12:35:25 2009  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.1
-       * Add both foo and nofoo for boolean flags, with --undefok (andychu)
-       * Better document how validators work (wojtekm)
-       * Improve binary-detection for bash-completion (mtamsky)
-       * Python: Add a concept of "key flags", used with --help (salcianu)
-       * Python: Robustify flag_values (salcianu)
-       * Python: Add a new DEFINE_bool alias (keir, andrewliu)
-       * Python: Do module introspection based on module name (dsturtevant)
-       * Fix autoconf a bit better, especially on windows and solaris (ajenjo)
-       * BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
-       * BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
-       * PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
-       * PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
-       * PORTABILITY: #include more headers to satify new gcc's (csilvers)
-       * INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
-
-Fri Oct  3 15:16:46 2008  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.0
-       * Add a missing newline to an error string (bcmills)
-       * (otherwise exactly the same as gflags 1.0rc2)
-
-Thu Sep 18 12:58:05 2008  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 1.0rc2
-       * Report current flag values in --helpxml (hdn)
-       * Fix compilation troubles with gcc 4.3.3 (simonb)
-       * BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
-       * BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
-       * BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
-       * BUG FIX: Fix python unittest for 64-bit builds (bcmills)
-       
-Tue Aug 19 16:15:48 2008
-
-       * google-gflags: version 1.0rc1
-       * Move #include files from google/ to gflags/ (csilvers)
-       * Small optimizations to reduce binary (library) size (jyrki)
-       * BUGFIX: forgot a std:: in one of the .h files (csilvers)
-       * Speed up locking by making sure calls are inlined (ajenjo)
-       * 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
-       * PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
-       * PORTABILITY: fix code to compile under Visual Studio (ajenjo)
-       * PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
-
-Mon Jul 21 23:01:38 2008  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 0.9
-       * Add the ability to validate a command-line flag (csilvers)
-       * Add completion support for commandline flags in bash (daven)
-       * Add -W compile flags to Makefile, when using gcc (csilvers)
-       * Allow helpstring to be NULL (cristianoc)
-       * Improved documentation of classes in the .cc file (csilvers)
-       * Fix python bug with AppendFlagValues + shortnames (jjtswan)
-       * Use bool instead of int for boolean flags in gflags.py (bcmills)
-       * Simplify the way we declare flags, now more foolproof (csilvers)
-       * Better error messages when bool flags collide (colohan)
-       * Only evaluate DEFINE_foo macro args once (csilvers)
-
-Wed Mar 26 15:20:18 2008  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 0.8
-       * Export DescribeOneFlag() in the API
-       * Add support for automatic line wrapping at 80 cols for gflags.py
-       * Bugfix: do not treat an isolated "-" the same as an isolated "--"
-       * Update rpm spec to point to Google Code rather than sourceforge (!)
-       * Improve documentation (including documenting thread-safety)
-       * Improve #include hygiene
-       * Improve testing
-       
-Thu Oct 18 11:33:20 2007  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 0.7
-       * Deal even more correctly with libpthread not linked in (csilvers)
-       * Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
-       * Be more accurate printing default flag values in --help (dsturtevant)
-       * Reduce .o file size a bit by using shorter namespace names (jeff)
-       * Use relative install path, so 'setup.py --home' works (csilvers)
-       * Notice when a boolean flag has a non-boolean default (bnmouli)
-       * Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
-       * Fix "no modules match" message for --helpshort, etc (hendrie)
-
-Wed Aug 15 07:35:51 2007  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 0.6
-       * Deal correctly with case that libpthread is not linked in (csilvers)
-       * Update Makefile/tests so we pass "make distcheck" (csilvers)
-       * Document and test that last assignment to a flag wins (wan)
-
-Tue Jun 12 15:23:42 2007  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 0.5
-       * Include all m4 macros in the distribution (csilvers)
-       * Python: Fix broken data_files field in setup.py (sidlon)
-       * Python: better string serliaizing and unparsing (abo, csimmons)
-       * Fix checks for NaN and inf to work with Mac OS X (csilvers)
-       
-Thu Apr 19 15:15:07 2007  Google Inc. <opensource@google.com>
-
-       * google-gflags: version 0.4
-       * Remove is_default from GetCommandLineFlagInfo (csilvers)
-       * Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
-       * A few doc typo cleanups (csilvers)
-
-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)
-
-Mon Jan 22 15:33:06 2007  Google Inc. <opensource@google.com>
-
-       * 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 Dec 13 12:37:19 2006  Google Inc. <opensource@google.com>
-
-       * google-gflags: initial release:
-       The gflags package contains a library that implements commandline
-       flags processing.  As such it's a replacement for getopt().  It
-       has increased flexibility, including built-in support for C++
-       types like string, and the ability to define flags in the source
-       file in which they're used.
diff --git a/extern/libmv/third_party/gflags/ChangeLog.txt b/extern/libmv/third_party/gflags/ChangeLog.txt
new file mode 100644 (file)
index 0000000..e14d88e
--- /dev/null
@@ -0,0 +1,208 @@
+* Sun Mar 20 2014 - Andreas Schuh <google-gflags@googlegroups.com>
+
+- gflags: version 2.1.1
+- Fixed issue 77: GFLAGS_IS_A_DLL expands to empty string in gflags_declare.h
+- Fixed issue 79: GFLAGS_NAMESPACE not expanded to actual namespace in gflags_declare.h
+- Fixed issue 80: Allow include path to differ from GFLAGS_NAMESPACE
+
+* Thu Mar 20 2014 - Andreas Schuh <google-gflags@googlegroups.com>
+
+- gflags: version 2.1.0
+- Build system configuration using CMake instead of autotools
+- CPack packaging support for Debian/Ubuntu, Red Hat, and Mac OS X
+- Fixed issue 54: Fix "invalid suffix on literal" (C++11)
+- Fixed issue 57: Use _strdup instead of strdup on Windows
+- Fixed issue 62: Change all preprocessor include guards to start with GFLAGS_
+- Fixed issue 64: Add DEFINE_validator macro
+- Fixed issue 73: Warnings in Visual Studio 2010 and unable to compile unit test
+
+* Wed Jan 25 2012 - Google Inc. <google-gflags@googlegroups.com>
+
+- gflags: version 2.0
+- Changed the 'official' gflags email in setup.py/etc
+- Renamed google-gflags.sln to gflags.sln
+- Changed copyright text to reflect Google's relinquished ownership
+
+* Tue Dec 20 2011 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.7
+- Add CommandLineFlagInfo::flag_ptr pointing to current storage (musji)
+- PORTING: flush after writing to stderr, needed on cygwin
+- PORTING: Clean up the GFLAGS_DLL_DECL stuff better
+- Fix a bug in StringPrintf() that affected large strings (csilvers)
+- Die at configure-time when g++ isn't installed
+
+* Fri Jul 29 2011 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.6
+- BUGFIX: Fix a bug where we were leaving out a required $(top_srcdir)
+- Fix definition of clstring (jyrki)
+- Split up flag declares into its own file (jyrki)
+- Add --version support (csilvers)
+- Update the README for gflags with static libs
+- Update acx_pthread.m4 for nostdlib
+- Change ReparseCommandLineFlags to return void (csilvers)
+- Some doc typofixes and example augmentation (various)
+
+* Mon Jan 24 2011 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.5
+- Better reporting of current vs default value (handler)
+- Add API for cleaning up of memory at program-exit (jmarantz)
+- Fix macros to work inside namespaces (csilvers)
+- Use our own string typedef in case string is redefined (csilvers)
+- Updated to autoconf 2.65
+
+* Wed Oct 13 2010 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.4
+- Add a check to prevent passing 0 to DEFINE_string (jorg)
+- Reduce compile (.o) size (jyrki)
+- Some small changes to quiet debug compiles (alexk)
+- PORTING: better support static linking on windows (csilvers)
+- DOCUMENTATION: change default values, use validators, etc.
+- Update the NEWS file to be non-empty
+- Add pkg-config (.pc) files for libgflags and libgflags_nothreads
+
+* Mon Jan  4 2010 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.3
+- PORTABILITY: can now build and run tests under MSVC (csilvers)
+- Remove the python gflags code, which is now its own package (tansell)
+- Clarify that "last flag wins" in the docs (csilvers)
+- Comment danger of using GetAllFlags in validators (wojtekm)
+- PORTABILITY: Some fixes necessary for c++0x (mboerger)
+- Makefile fix: $(srcdir) -> $(top_srcdir) in one place (csilvres)
+- INSTALL: autotools to autoconf v2.64 + automake v1.11 (csilvers)
+
+* Thu Sep 10 2009 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.2
+- PORTABILITY: can now build and run tests under mingw (csilvers)
+- Using a string arg for a bool flag is a compile-time error (rbayardo)
+- Add --helpxml to gflags.py (salcianu)
+- Protect against a hypothetical global d'tor mutex problem (csilvers)
+- BUGFIX: can now define a flag after 'using namespace google' (hamaji)
+
+* Tue Apr 14 2009 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.1
+- Add both foo and nofoo for boolean flags, with --undefok (andychu)
+- Better document how validators work (wojtekm)
+- Improve binary-detection for bash-completion (mtamsky)
+- Python: Add a concept of "key flags", used with --help (salcianu)
+- Python: Robustify flag_values (salcianu)
+- Python: Add a new DEFINE_bool alias (keir, andrewliu)
+- Python: Do module introspection based on module name (dsturtevant)
+- Fix autoconf a bit better, especially on windows and solaris (ajenjo)
+- BUG FIX: gflags_nothreads was linking against the wrong lib (ajenjo)
+- BUG FIX: threads-detection failed on FreeBSD; replace it (ajenjo)
+- PORTABILITY: Quiet an internal compiler error with SUSE 10 (csilvers)
+- PORTABILITY: Update deb.sh for more recenty debuilds (csilvers)
+- PORTABILITY: #include more headers to satify new gcc's (csilvers)
+- INSTALL: Updated to autoconf 2.61 and libtool 1.5.26 (csilvers)
+
+* Fri Oct  3 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.0
+- Add a missing newline to an error string (bcmills)
+- (otherwise exactly the same as gflags 1.0rc2)
+
+* Thu Sep 18 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.0rc2
+- Report current flag values in --helpxml (hdn)
+- Fix compilation troubles with gcc 4.3.3 (simonb)
+- BUG FIX: I was missing a std:: in DECLARE_string (csilvers)
+- BUG FIX: Clarify in docs how to specify --bool flags (csilvers)
+- BUG FIX: Fix --helpshort for source files not in a subdir (csilvers)
+- BUG FIX: Fix python unittest for 64-bit builds (bcmills)
+
+* Tue Aug 19 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 1.0rc1
+- Move #include files from google/ to gflags/ (csilvers)
+- Small optimizations to reduce binary (library) size (jyrki)
+- BUGFIX: forgot a std:: in one of the .h files (csilvers)
+- Speed up locking by making sure calls are inlined (ajenjo)
+- 64-BIT COMPATIBILITY: Use %PRId64 instead of %lld (csilvers)
+- PORTABILITY: fix Makefile to work with Cygwin (ajenjo)
+- PORTABILITY: fix code to compile under Visual Studio (ajenjo)
+- PORTABILITY: fix code to compile under Solaris 10 with CC (csilvers)
+
+* Mon Jul 21 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.9
+- Add the ability to validate a command-line flag (csilvers)
+- Add completion support for commandline flags in bash (daven)
+- Add -W compile flags to Makefile, when using gcc (csilvers)
+- Allow helpstring to be NULL (cristianoc)
+- Improved documentation of classes in the .cc file (csilvers)
+- Fix python bug with AppendFlagValues + shortnames (jjtswan)
+- Use bool instead of int for boolean flags in gflags.py (bcmills)
+- Simplify the way we declare flags, now more foolproof (csilvers)
+- Better error messages when bool flags collide (colohan)
+- Only evaluate DEFINE_foo macro args once (csilvers)
+
+* Wed Mar 26 2008 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.8
+- Export DescribeOneFlag() in the API
+- Add support for automatic line wrapping at 80 cols for gflags.py
+- Bugfix: do not treat an isolated "-" the same as an isolated "--"
+- Update rpm spec to point to Google Code rather than sourceforge (!)
+- Improve documentation (including documenting thread-safety)
+- Improve #include hygiene
+- Improve testing
+
+* Thu Oct 18 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.7
+- Deal even more correctly with libpthread not linked in (csilvers)
+- Add STRIP_LOG, an improved DO_NOT_SHOW_COMMANDLINE_HELP (sioffe)
+- Be more accurate printing default flag values in --help (dsturtevant)
+- Reduce .o file size a bit by using shorter namespace names (jeff)
+- Use relative install path, so 'setup.py --home' works (csilvers)
+- Notice when a boolean flag has a non-boolean default (bnmouli)
+- Broaden --helpshort to match foo-main.cc and foo_main.cc (hendrie)
+- Fix "no modules match" message for --helpshort, etc (hendrie)
+
+* Wed Aug 15 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.6
+- Deal correctly with case that libpthread is not linked in (csilvers)
+- Update Makefile/tests so we pass "make distcheck" (csilvers)
+- Document and test that last assignment to a flag wins (wan)
+
+* Tue Jun 12 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.5
+- Include all m4 macros in the distribution (csilvers)
+- Python: Fix broken data_files field in setup.py (sidlon)
+- Python: better string serliaizing and unparsing (abo, csimmons)
+- Fix checks for NaN and inf to work with Mac OS X (csilvers)
+
+* Thu Apr 19 2007 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.4
+- Remove is_default from GetCommandLineFlagInfo (csilvers)
+- Portability fixes: includes, strtoll, gcc4.3 errors (csilvers)
+- A few doc typo cleanups (csilvers)
+
+* Wed Mar 28 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)
+
+* Mon Jan 22 2007 - Google Inc. <opensource@google.com>
+
+- 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 Dec 13 2006 - Google Inc. <opensource@google.com>
+
+- google-gflags: version 0.1
similarity index 61%
rename from extern/libmv/third_party/gflags/NEWS
rename to extern/libmv/third_party/gflags/NEWS.txt
index ffc0127d91eba2778f31b3135a46f1c9a413d95a..74186071129bfc86d444682ba1b2925a874f84ac 100644 (file)
@@ -1,4 +1,86 @@
-== 25 January 2012 ==
+=== 30 March 2014 ===
+
+I've just released gflags 2.1.1.
+
+This release fixes a few bugs in the configuration of gflags_declare.h
+and adds a separate GFLAGS_INCLUDE_DIR CMake variable to the build configuration.
+Setting GFLAGS_NAMESPACE to "google" no longer changes also the include
+path of the public header files. This allows the use of the library with
+other Google projects such as glog which still use the deprecated "google"
+namespace for the gflags library, but include it as "gflags/gflags.h".
+
+=== 20 March 2014 ===
+
+I've just released gflags 2.1.
+
+The major changes are the use of CMake for the build configuration instead
+of the autotools and packaging support through CPack. The default namespace
+of all C++ symbols is now "gflags" instead of "google". This can be
+configured via the GFLAGS_NAMESPACE variable.
+
+This release compiles with all major compilers without warnings and passed
+the unit tests on  Ubuntu 12.04, Windows 7 (Visual Studio 2008 and 2010,
+Cygwin, MinGW), and Mac OS X (Xcode 5.1).
+
+The SVN repository on Google Code is now frozen and replaced by a Git
+repository such that it can be used as Git submodule by projects. The main
+hosting of this project remains at Google Code. Thanks to the distributed
+character of Git, I can push (and pull) changes from both GitHub and Google Code
+in order to keep the two public repositories in sync.
+When fixing an issue for a pull request through either of these hosting
+platforms, please reference the issue number as 
+[https://code.google.com/p/support/wiki/IssueTracker#Integration_with_version_control described here].
+For the further development, I am following the
+[http://nvie.com/posts/a-successful-git-branching-model/ Git branching model]
+with feature branch names prefixed by "feature/" and bugfix branch names
+prefixed by "bugfix/", respectively.
+
+Binary and source [https://github.com/schuhschuh/gflags/releases packages] are available on GitHub.
+
+
+=== 14 January 2013 ===
+
+The migration of the build system to CMake is almost complete.
+What remains to be done is rewriting the tests in Python such they can be
+executed on non-Unix platforms and splitting them up into separate CTest tests.
+Though merging these changes into the master branch yet remains to be done,
+it is recommended to already start using the
+[https://github.com/schuhschuh/gflags/tree/cmake-migration cmake-migration] branch.
+
+
+=== 20 April 2013 ===
+
+More than a year has past since I (Andreas) took over the maintenance for
+`gflags`. Only few minor changes have been made since then, much to my regret.
+To get more involved and stimulate participation in the further
+development of the library, I moved the project source code today to
+[https://github.com/schuhschuh/gflags GitHub].
+I believe that the strengths of [http://git-scm.com/ Git] will allow for better community collaboration
+as well as ease the integration of changes made by others. I encourage everyone
+who would like to contribute to send me pull requests.
+Git's lightweight feature branches will also provide the right tool for more
+radical changes which should only be merged back into the master branch
+after these are complete and implement the desired behavior.
+
+The SVN repository remains accessible at Google Code and I will keep the
+master branch of the Git repository hosted at GitHub and the trunk of the
+Subversion repository synchronized. Initially, I was going to simply switch the
+Google Code project to Git, but in this case the SVN repository would be
+frozen and force everyone who would like the latest development changes to
+use Git as well. Therefore I decided to host the public Git repository at GitHub
+instead.
+
+Please continue to report any issues with gflags on Google Code. The GitHub project will
+only be used to host the Git repository.
+
+One major change of the project structure I have in mind for the next weeks
+is the migration from autotools to [http://www.cmake.org/ CMake].
+Check out the (unstable!)
+[https://github.com/schuhschuh/gflags/tree/cmake-migration cmake-migration]
+branch on GitHub for details.
+
+
+=== 25 January 2012 ===
 
 I've just released gflags 2.0.
 
@@ -128,7 +210,7 @@ If you've tried to install a .rpm or .deb and it doesn't work for you,
 let me know.  I'm excited to finally have 64-bit package files, but
 there may still be some wrinkles in the new system to iron out.
 
-===1 October 2008===
+=== 1 October 2008 ===
 
 gflags 1.0rc2 was out for a few weeks without any issues, so gflags
 1.0 is now released.  This is much like gflags 0.9.  The major change
index b310c57ac344ae4c0c6da0b696aea6e4d61c0a4e..f4310b39bbbc115fa5f3b81e1111d6ed37e4d314 100644 (file)
@@ -1,16 +1,18 @@
 Project: Google Flags
 URL: http://code.google.com/p/google-gflags/
 License: New BSD
-Upstream version: 2.0
+Upstream version: 2.1.1
 Local modifications:
 
-- Flattened the tree and only included files needed for libmv. This involved
-  changing some of the includes to point to the current directory instead of a
-  nested gflags directory.
+- Flattened the tree and only included files needed for libmv.
 
-- Added a poor-man's version of upstream's port.cc/h to make gflags compile on
-  windows. This isn't sufficient but is a stopgap for now.
+- config.h was originally generated on linux machine with some
+  further tweaks:
 
-- Added -fPIC flag, so shared libraries from Ceres could be linked against static glog
+  * OS_WINDOWS need to be conditinally defined from inside #ifdef WIN32
+  * Same applies yo HAVE_SHLWAPI_H
+  * Disabeld HAVE_FNMATCH_H
+
+- Removed attribute(unused) from FlagSaver.
 
   TODO(keir): Import and use gflags for Windows from upstream.
index 03ed03ca99bed9b37d1c513c14f6cd29e5887478..986329ba1c0cbfb79f488d3972788a3108e14127 100644 (file)
-/* src/config.h.  Generated from config.h.in by configure.  */
-/* src/config.h.in.  Generated from configure.ac by autoheader.  */
+/* Generated from config.h.in during build configuration using CMake. */
 
-/* Always the empty-string on non-windows systems. On windows, should be
-   "__declspec(dllexport)". This way, when we compile the dll, we export our
-   functions/classes. It's safe to define this here because config.h is only
-   used internally, to compile the DLL, and every DLL source file #includes
-   "config.h" before anything else. */
-#define GFLAGS_DLL_DECL /**/
+// Note: This header file is only used internally. It is not part of public interface!
 
-/* Namespace for Google classes */
-#define GOOGLE_NAMESPACE ::google
+// ---------------------------------------------------------------------------
+// System checks
 
-/* Define to 1 if you have the <dlfcn.h> header file. */
-#define HAVE_DLFCN_H 1
+// Define if you build this library for a MS Windows OS.
+#ifdef WIN32
+#  define OS_WINDOWS
+#endif
 
-/* Define to 1 if you have the <fnmatch.h> header file. */
-/* #ubdef HAVE_FNMATCH_H 1 */
+// Define if you have the <stdint.h> header file.
+#define HAVE_STDINT_H
 
-/* Define to 1 if you have the <inttypes.h> header file. */
-#define HAVE_INTTYPES_H 1
+// Define if you have the <sys/types.h> header file.
+#define HAVE_SYS_TYPES_H
 
-/* Define to 1 if you have the <memory.h> header file. */
-#define HAVE_MEMORY_H 1
+// Define if you have the <inttypes.h> header file.
+#define HAVE_INTTYPES_H
 
-/* define if the compiler implements namespaces */
-#define HAVE_NAMESPACES 1
+// Define if you have the <sys/stat.h> header file.
+#define HAVE_SYS_STAT_H
 
-/* Define if you have POSIX threads libraries and header files. */
-#define HAVE_PTHREAD 1
+// Define if you have the <unistd.h> header file.
+#define HAVE_UNISTD_H
 
-/* Define to 1 if you have the <stdint.h> header file. */
-#define HAVE_STDINT_H 1
+// Define if you have the <fnmatch.h> header file.
+/* #undef HAVE_FNMATCH_H */
 
-/* Define to 1 if you have the <stdlib.h> header file. */
-#define HAVE_STDLIB_H 1
+// Define if you have the <shlwapi.h> header file (Windows 2000/XP).
+#ifdef WIN32
+#  define HAVE_SHLWAPI_H
+#endif
 
-/* Define to 1 if you have the <strings.h> header file. */
-#define HAVE_STRINGS_H 1
+// Define if you have the strtoll function.
+#define HAVE_STRTOLL
 
-/* Define to 1 if you have the <string.h> header file. */
-#define HAVE_STRING_H 1
+// Define if you have the strtoq function.
+/* #undef HAVE_STRTOQ */
 
-/* Define to 1 if you have the `strtoll' function. */
-#define HAVE_STRTOLL 1
+// Define if you have the <pthread.h> header file.
+#define HAVE_PTHREAD
 
-/* Define to 1 if you have the `strtoq' function. */
-#define HAVE_STRTOQ 1
+// Define if your pthread library defines the type pthread_rwlock_t
+#define HAVE_RWLOCK
 
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#define HAVE_SYS_STAT_H 1
+// gcc requires this to get PRId64, etc.
+#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
+#  define __STDC_FORMAT_MACROS 1
+#endif
 
-/* Define to 1 if you have the <sys/types.h> header file. */
-#define HAVE_SYS_TYPES_H 1
+// ---------------------------------------------------------------------------
+// Package information
 
-/* Define to 1 if you have the <unistd.h> header file. */
-#define HAVE_UNISTD_H 1
+// Name of package.
+#define PACKAGE gflags
 
-/* define if your compiler has __attribute__ */
-#define HAVE___ATTRIBUTE__ 1
+// Define to the full name of this package.
+#define PACKAGE_NAME gflags
 
-/* Define to the sub-directory in which libtool stores uninstalled libraries.
-   */
-#define LT_OBJDIR ".libs/"
+// Define to the full name and version of this package.
+#define PACKAGE_STRING gflags 2.1.1
 
-/* Name of package */
-#define PACKAGE "gflags"
+// Define to the one symbol short name of this package.
+#define PACKAGE_TARNAME gflags-2.1.1
 
-/* Define to the address where bug reports for this package should be sent. */
-#define PACKAGE_BUGREPORT "google-gflags@googlegroups.com"
+// Define to the version of this package.
+#define PACKAGE_VERSION 2.1.1
 
-/* Define to the full name of this package. */
-#define PACKAGE_NAME "gflags"
+// Version number of package.
+#define VERSION PACKAGE_VERSION
 
-/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "gflags 2.0"
+// Define to the address where bug reports for this package should be sent.
+#define PACKAGE_BUGREPORT https://code.google.com/p/gflags/issues/
 
-/* Define to the one symbol short name of this package. */
-#define PACKAGE_TARNAME "gflags"
+// Namespace of gflags library symbols.
+#define GFLAGS_NAMESPACE gflags
 
-/* Define to the version of this package. */
-#define PACKAGE_VERSION "2.0"
+// ---------------------------------------------------------------------------
+// Path separator
+#ifndef PATH_SEPARATOR
+#  ifdef OS_WINDOWS
+#    define PATH_SEPARATOR  '\\'
+#  else
+#    define PATH_SEPARATOR  '/'
+#  endif
+#endif
 
-/* Define to necessary symbol if this constant uses a non-standard name on
-   your system. */
-/* #undef PTHREAD_CREATE_JOINABLE */
+// ---------------------------------------------------------------------------
+// Windows
 
-/* Define to 1 if you have the ANSI C header files. */
-#define STDC_HEADERS 1
+// Whether gflags library is a DLL.
+#ifndef GFLAGS_IS_A_DLL
+#  define GFLAGS_IS_A_DLL 0
+#endif
 
-/* the namespace where STL code like vector<> is defined */
-#define STL_NAMESPACE std
-
-/* Version number of package */
-#define VERSION "2.0"
-
-/* Stops putting the code inside the Google namespace */
-#define _END_GOOGLE_NAMESPACE_ }
-
-/* Puts following code inside the Google namespace */
-#define _START_GOOGLE_NAMESPACE_ namespace google {
+// Always export symbols when compiling a shared library as this file is only
+// included by internal modules when building the gflags library itself.
+// The gflags_declare.h header file will set it to import these symbols otherwise.
+#ifndef GFLAGS_DLL_DECL
+#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
+#    define GFLAGS_DLL_DECL __declspec(dllexport)
+#  else
+#    define GFLAGS_DLL_DECL
+#  endif
+#endif
+// Flags defined by the gflags library itself must be exported
+#ifndef GFLAGS_DLL_DEFINE_FLAG
+#  define GFLAGS_DLL_DEFINE_FLAG GFLAGS_DLL_DECL
+#endif
+
+#ifdef OS_WINDOWS
+// The unittests import the symbols of the shared gflags library
+#  if GFLAGS_IS_A_DLL && defined(_MSC_VER)
+#    define GFLAGS_DLL_DECL_FOR_UNITTESTS __declspec(dllimport)
+#  endif
+#  include "windows_port.h"
+#endif
index 4ba2b6f393c5b2de7b45ac36ed00442b55c77623..285050fe9ec34defc1e6f2cf7426f72240fbd0d7 100644 (file)
 // other hand, hooks into CommandLineFlagParser.  Other API functions
 // are, similarly, mostly hooks into the functionality described above.
 
-// This comes first to ensure we define __STDC_FORMAT_MACROS in time.
 #include "config.h"
-#if defined(HAVE_INTTYPES_H) && !defined(__STDC_FORMAT_MACROS)
-# define __STDC_FORMAT_MACROS 1   // gcc requires this to get PRId64, etc.
-#endif
+#include "gflags.h"
 
-#include "gflags/gflags.h"
 #include <assert.h>
 #include <ctype.h>
 #include <errno.h>
-#ifdef HAVE_FNMATCH_H
-# include <fnmatch.h>
+#if defined(HAVE_FNMATCH_H)
+#  include <fnmatch.h>
+#elif defined(HAVE_SHLWAPI_H)
+#  include <shlwapi.h>
 #endif
 #include <stdarg.h> // For va_list and related operations
 #include <stdio.h>
 #include <string>
 #include <utility>     // for pair<>
 #include <vector>
+
 #include "mutex.h"
 #include "util.h"
 
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR  '/'
-#endif
-
-
 // Special flags, type 1: the 'recursive' flags.  They set another flag's val.
-DEFINE_string(flagfile, "",
-              "load flags from file");
-DEFINE_string(fromenv, "",
-              "set flags from the environment"
-              " [use 'export FLAGS_flag1=value']");
-DEFINE_string(tryfromenv, "",
-              "set flags from the environment if present");
+DEFINE_string(flagfile,   "", "load flags from file");
+DEFINE_string(fromenv,    "", "set flags from the environment"
+                              " [use 'export FLAGS_flag1=value']");
+DEFINE_string(tryfromenv, "", "set flags from the environment if present");
 
 // Special flags, type 2: the 'parsing' flags.  They modify how we parse.
-DEFINE_string(undefok, "",
-              "comma-separated list of flag names that it is okay to specify "
-              "on the command line even if the program does not define a flag "
-              "with that name.  IMPORTANT: flags in this list that have "
-              "arguments MUST use the flag=value format");
+DEFINE_string(undefok, "", "comma-separated list of flag names that it is okay to specify "
+                           "on the command line even if the program does not define a flag "
+                           "with that name.  IMPORTANT: flags in this list that have "
+                           "arguments MUST use the flag=value format");
 
-_START_GOOGLE_NAMESPACE_
+namespace GFLAGS_NAMESPACE {
 
 using std::map;
 using std::pair;
@@ -206,7 +196,7 @@ class FlagValue {
 
  private:
   friend class CommandLineFlag;  // for many things, including Validate()
-  friend class GOOGLE_NAMESPACE::FlagSaverImpl;  // calls New()
+  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // calls New()
   friend class FlagRegistry;     // checks value_buffer_ for flags_by_ptr_ map
   template <typename T> friend T GetFromEnv(const char*, const char*, T);
   friend bool TryParseLocked(const CommandLineFlag*, FlagValue*,
@@ -348,13 +338,13 @@ string FlagValue::ToString() const {
     case FV_BOOL:
       return VALUE_AS(bool) ? "true" : "false";
     case FV_INT32:
-      snprintf(intbuf, sizeof(intbuf), "%"PRId32, VALUE_AS(int32));
+      snprintf(intbuf, sizeof(intbuf), "%" PRId32, VALUE_AS(int32));
       return intbuf;
     case FV_INT64:
-      snprintf(intbuf, sizeof(intbuf), "%"PRId64, VALUE_AS(int64));
+      snprintf(intbuf, sizeof(intbuf), "%" PRId64, VALUE_AS(int64));
       return intbuf;
     case FV_UINT64:
-      snprintf(intbuf, sizeof(intbuf), "%"PRIu64, VALUE_AS(uint64));
+      snprintf(intbuf, sizeof(intbuf), "%" PRIu64, VALUE_AS(uint64));
       return intbuf;
     case FV_DOUBLE:
       snprintf(intbuf, sizeof(intbuf), "%.17g", VALUE_AS(double));
@@ -406,8 +396,7 @@ const char* FlagValue::TypeName() const {
     assert(false);
     return "";
   }
-  // Directly indexing the strigns in the 'types' string, each of them
-  // is 7 bytes long.
+  // Directly indexing the strings in the 'types' string, each of them is 7 bytes long.
   return &types[type_ * 7];
 }
 
@@ -504,7 +493,7 @@ class CommandLineFlag {
  private:
   // for SetFlagLocked() and setting flags_by_ptr_
   friend class FlagRegistry;
-  friend class GOOGLE_NAMESPACE::FlagSaverImpl;  // for cloning the values
+  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // for cloning the values
   // set validate_fn
   friend bool AddFlagValidator(const void*, ValidateFnProto);
 
@@ -671,9 +660,9 @@ class FlagRegistry {
   static FlagRegistry* GlobalRegistry();   // returns a singleton registry
 
  private:
-  friend class GOOGLE_NAMESPACE::FlagSaverImpl;  // reads all the flags in order to copy them
+  friend class GFLAGS_NAMESPACE::FlagSaverImpl;  // reads all the flags in order to copy them
   friend class CommandLineFlagParser;    // for ValidateAllFlags
-  friend void GOOGLE_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
+  friend void GFLAGS_NAMESPACE::GetAllFlags(vector<CommandLineFlagInfo>*);
 
   // The map from name to flag, for FindFlagLocked().
   typedef map<const char*, CommandLineFlag*, StringCmp> FlagMap;
@@ -1003,8 +992,8 @@ static string ReadFileIntoString(const char* filename) {
   const int kBufSize = 8092;
   char buffer[kBufSize];
   string s;
-  FILE* fp = fopen(filename, "r");
-  if (!fp)  PFATAL(filename);
+  FILE* fp;
+  if ((errno = SafeFOpen(&fp, filename, "r")) != 0) PFATAL(filename);
   size_t n;
   while ( (n=fread(buffer, 1, kBufSize, fp)) > 0 ) {
     if (ferror(fp))  PFATAL(filename);
@@ -1148,8 +1137,8 @@ string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
     }
 
     const string envname = string("FLAGS_") + string(flagname);
-    const char* envval = getenv(envname.c_str());
-    if (!envval) {
+       string envval;
+       if (!SafeGetEnv(envname.c_str(), envval)) {
       if (errors_are_fatal) {
         error_flags_[flagname] = (string(kError) + envname +
                                   " not found in environment\n");
@@ -1158,15 +1147,14 @@ string CommandLineFlagParser::ProcessFromenvLocked(const string& flagval,
     }
 
     // Avoid infinite recursion.
-    if ((strcmp(envval, "fromenv") == 0) ||
-        (strcmp(envval, "tryfromenv") == 0)) {
+    if (envval == "fromenv" || envval == "tryfromenv") {
       error_flags_[flagname] =
           StringPrintf("%sinfinite recursion on environment flag '%s'\n",
-                       kError, envval);
+                       kError, envval.c_str());
       continue;
     }
 
-    msg += ProcessSingleOptionLocked(flag, envval, set_mode);
+    msg += ProcessSingleOptionLocked(flag, envval.c_str(), set_mode);
   }
   return msg;
 }
@@ -1318,13 +1306,12 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
         // We try matching both against the full argv0 and basename(argv0)
         if (glob == ProgramInvocationName()       // small optimization
             || glob == ProgramInvocationShortName()
-#ifdef HAVE_FNMATCH_H
-            || fnmatch(glob.c_str(),
-                       ProgramInvocationName(),
-                       FNM_PATHNAME) == 0
-            || fnmatch(glob.c_str(),
-                       ProgramInvocationShortName(),
-                       FNM_PATHNAME) == 0
+#if defined(HAVE_FNMATCH_H)
+            || fnmatch(glob.c_str(), ProgramInvocationName(),      FNM_PATHNAME) == 0
+            || fnmatch(glob.c_str(), ProgramInvocationShortName(), FNM_PATHNAME) == 0
+#elif defined(HAVE_SHLWAPI_H)
+            || PathMatchSpec(glob.c_str(), ProgramInvocationName())
+            || PathMatchSpec(glob.c_str(), ProgramInvocationShortName())
 #endif
             ) {
           flags_are_relevant = true;
@@ -1346,14 +1333,15 @@ string CommandLineFlagParser::ProcessOptionsFromStringLocked(
 
 template<typename T>
 T GetFromEnv(const char *varname, const char* type, T dflt) {
-  const char* const valstr = getenv(varname);
-  if (!valstr)
-    return dflt;
-  FlagValue ifv(new T, type, true);
-  if (!ifv.ParseFrom(valstr))
-    ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
-                varname, valstr);
-  return OTHER_VALUE_AS(ifv, T);
+  std::string valstr;
+  if (SafeGetEnv(varname, valstr)) {
+    FlagValue ifv(new T, type, true);
+    if (!ifv.ParseFrom(valstr.c_str())) {
+      ReportError(DIE, "ERROR: error parsing env variable '%s' with value '%s'\n",
+                  varname, valstr.c_str());
+       }
+    return OTHER_VALUE_AS(ifv, T);
+  } else return dflt;
 }
 
 bool AddFlagValidator(const void* flag_ptr, ValidateFnProto validate_fn_proto) {
@@ -1765,8 +1753,8 @@ bool ReadFlagsFromString(const string& flagfilecontents,
 
 // TODO(csilvers): nix prog_name in favor of ProgramInvocationShortName()
 bool AppendFlagsIntoFile(const string& filename, const char *prog_name) {
-  FILE *fp = fopen(filename.c_str(), "a");
-  if (!fp) {
+  FILE *fp;
+  if (SafeFOpen(&fp, filename.c_str(), "a") != 0) {
     return false;
   }
 
@@ -1824,10 +1812,18 @@ uint64 Uint64FromEnv(const char *v, uint64 dflt) {
 double DoubleFromEnv(const char *v, double dflt) {
   return GetFromEnv(v, "double", dflt);
 }
+
+#ifdef _MSC_VER
+#  pragma warning(push)
+#  pragma warning(disable: 4996) // ignore getenv security warning
+#endif
 const char *StringFromEnv(const char *varname, const char *dflt) {
   const char* const val = getenv(varname);
   return val ? val : dflt;
 }
+#ifdef _MSC_VER
+#  pragma warning(pop)
+#endif
 
 
 // --------------------------------------------------------------------
@@ -1957,4 +1953,5 @@ void ShutDownCommandLineFlags() {
   FlagRegistry::DeleteGlobalRegistry();
 }
 
-_END_GOOGLE_NAMESPACE_
+
+} // namespace GFLAGS_NAMESPACE
index e69812c8c38cb9a3700f0f84cdf14d4c33dff4be..a4f094068082c2bbb5ba468bfe585d5509cfc009 100644 (file)
 //   other thread is writing to the variable or calling non-const
 //   methods of this class.
 
-#ifndef BASE_COMMANDLINEFLAGS_H_
-#define BASE_COMMANDLINEFLAGS_H_
+#ifndef GFLAGS_GFLAGS_H_
+#define GFLAGS_GFLAGS_H_
 
 #include <string>
 #include <vector>
-#include "gflags_declare.h"    // IWYU pragma: export
-namespace google {
 
-//
-// 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.
-//
-#define GFLAGS_DLL_DECL  /* rewritten to be non-empty in windows dir */
-#define GFLAGS_DLL_DEFINE_FLAG  /* rewritten to be non-empty in windows dir */
+#include "gflags_declare.h" // IWYU pragma: export
+
+
+// We always want to export variables defined in user code
+#ifndef GFLAGS_DLL_DEFINE_FLAG
+#  ifdef _MSC_VER
+#    define GFLAGS_DLL_DEFINE_FLAG __declspec(dllexport)
+#  else
+#    define GFLAGS_DLL_DEFINE_FLAG
+#  endif
+#endif
+
+
+namespace gflags {
 
 
 // --------------------------------------------------------------------
@@ -121,19 +126,17 @@ namespace google {
 // Returns true if successfully registered, false if not (because the
 // first argument doesn't point to a command-line flag, or because a
 // validator is already registered for this flag).
-extern bool RegisterFlagValidator(const bool* flag,
-                                  bool (*validate_fn)(const char*, bool));
-extern bool RegisterFlagValidator(const int32* flag,
-                                  bool (*validate_fn)(const char*, int32));
-extern bool RegisterFlagValidator(const int64* flag,
-                                  bool (*validate_fn)(const char*, int64));
-extern bool RegisterFlagValidator(const uint64* flag,
-                                  bool (*validate_fn)(const char*, uint64));
-extern bool RegisterFlagValidator(const double* flag,
-                                  bool (*validate_fn)(const char*, double));
-extern bool RegisterFlagValidator(const std::string* flag,
-                                  bool (*validate_fn)(const char*,
-                                                      const std::string&));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const bool*        flag, bool (*validate_fn)(const char*, bool));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int32*       flag, bool (*validate_fn)(const char*, int32));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const int64*       flag, bool (*validate_fn)(const char*, int64));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const uint64*      flag, bool (*validate_fn)(const char*, uint64));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const double*      flag, bool (*validate_fn)(const char*, double));
+extern GFLAGS_DLL_DECL bool RegisterFlagValidator(const std::string* flag, bool (*validate_fn)(const char*, const std::string&));
+
+// Convenience macro for the registration of a flag validator
+#define DEFINE_validator(name, validator) \
+    static const bool name##_validator_registered = \
+            gflags::RegisterFlagValidator(&FLAGS_##name, validator)
 
 
 // --------------------------------------------------------------------
@@ -146,19 +149,20 @@ extern bool RegisterFlagValidator(const std::string* flag,
 // In addition to accessing flags, you can also access argv[0] (the program
 // name) and argv (the entire commandline), which we sock away a copy of.
 // These variables are static, so you should only set them once.
-
-struct GFLAGS_DLL_DECL CommandLineFlagInfo {
+//
+// No need to export this data only structure from DLL, avoiding VS warning 4251.
+struct CommandLineFlagInfo {
   std::string name;            // the name of the flag
   std::string type;            // the type of the flag: int32, etc
   std::string description;     // the "help text" associated with the flag
   std::string current_value;   // the current value, as a string
   std::string default_value;   // the default value, as a string
   std::string filename;        // 'cleaned' version of filename holding the flag
-  bool has_validator_fn;  // true if RegisterFlagValidator called on this flag
-  bool is_default;        // true if the flag has the default value and
-                          // has not been set explicitly from the cmdline
-                          // or via SetCommandLineOption
-  const void* flag_ptr;   // pointer to the flag's current value (i.e. FLAGS_foo)
+  bool has_validator_fn;       // true if RegisterFlagValidator called on this flag
+  bool is_default;             // true if the flag has the default value and
+                               // has not been set explicitly from the cmdline
+                               // or via SetCommandLineOption
+  const void* flag_ptr;        // pointer to the flag's current value (i.e. FLAGS_foo)
 };
 
 // Using this inside of a validator is a recipe for a deadlock.
@@ -166,34 +170,34 @@ struct GFLAGS_DLL_DECL CommandLineFlagInfo {
 // call validators during ParseAllFlags.
 // Also make sure then to uncomment the corresponding unit test in
 // gflags_unittest.sh
-extern void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
+extern GFLAGS_DLL_DECL void GetAllFlags(std::vector<CommandLineFlagInfo>* OUTPUT);
 // These two are actually defined in gflags_reporting.cc.
-extern void ShowUsageWithFlags(const char *argv0);  // what --help does
-extern void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
+extern GFLAGS_DLL_DECL void ShowUsageWithFlags(const char *argv0);  // what --help does
+extern GFLAGS_DLL_DECL void ShowUsageWithFlagsRestrict(const char *argv0, const char *restrict);
 
 // Create a descriptive string for a flag.
 // Goes to some trouble to make pretty line breaks.
-extern std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
+extern GFLAGS_DLL_DECL std::string DescribeOneFlag(const CommandLineFlagInfo& flag);
 
 // Thread-hostile; meant to be called before any threads are spawned.
-extern void SetArgv(int argc, const char** argv);
+extern GFLAGS_DLL_DECL void SetArgv(int argc, const char** argv);
 
 // The following functions are thread-safe as long as SetArgv() is
 // only called before any threads start.
-extern const std::vector<std::string>& GetArgvs();
-extern const char* GetArgv();                 // all of argv as a string
-extern const char* GetArgv0();                // only argv0
-extern uint32 GetArgvSum();                   // simple checksum of argv
-extern const char* ProgramInvocationName();   // argv0, or "UNKNOWN" if not set
-extern const char* ProgramInvocationShortName();   // basename(argv0)
+extern GFLAGS_DLL_DECL const std::vector<std::string>& GetArgvs();
+extern GFLAGS_DLL_DECL const char* GetArgv();                      // all of argv as a string
+extern GFLAGS_DLL_DECL const char* GetArgv0();                     // only argv0
+extern GFLAGS_DLL_DECL uint32 GetArgvSum();                        // simple checksum of argv
+extern GFLAGS_DLL_DECL const char* ProgramInvocationName();        // argv0, or "UNKNOWN" if not set
+extern GFLAGS_DLL_DECL const char* ProgramInvocationShortName();   // basename(argv0)
 
 // ProgramUsage() is thread-safe as long as SetUsageMessage() is only
 // called before any threads start.
-extern const char* ProgramUsage();            // string set by SetUsageMessage()
+extern GFLAGS_DLL_DECL const char* ProgramUsage();                 // string set by SetUsageMessage()
 
 // VersionString() is thread-safe as long as SetVersionString() is only
 // called before any threads start.
-extern const char* VersionString();          // string set by SetVersionString()
+extern GFLAGS_DLL_DECL const char* VersionString();                // string set by SetVersionString()
 
 
 
@@ -207,17 +211,16 @@ extern const char* VersionString();          // string set by SetVersionString()
 
 // Return true iff the flagname was found.
 // OUTPUT is set to the flag's value, or unchanged if we return false.
-extern bool GetCommandLineOption(const char* name, std::string* OUTPUT);
+extern GFLAGS_DLL_DECL bool GetCommandLineOption(const char* name, std::string* OUTPUT);
 
 // Return true iff the flagname was found. OUTPUT is set to the flag's
 // CommandLineFlagInfo or unchanged if we return false.
-extern bool GetCommandLineFlagInfo(const char* name,
-                                   CommandLineFlagInfo* OUTPUT);
+extern GFLAGS_DLL_DECL bool GetCommandLineFlagInfo(const char* name, CommandLineFlagInfo* OUTPUT);
 
 // Return the CommandLineFlagInfo of the flagname.  exit() if name not found.
 // Example usage, to check if a flag's value is currently the default value:
 //   if (GetCommandLineFlagInfoOrDie("foo").is_default) ...
-extern CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
+extern GFLAGS_DLL_DECL CommandLineFlagInfo GetCommandLineFlagInfoOrDie(const char* name);
 
 enum GFLAGS_DLL_DECL FlagSettingMode {
   // update the flag's value (can call this multiple times).
@@ -239,9 +242,8 @@ enum GFLAGS_DLL_DECL FlagSettingMode {
 // non-empty else.
 
 // SetCommandLineOption uses set_mode == SET_FLAGS_VALUE (the common case)
-extern std::string SetCommandLineOption(const char* name, const char* value);
-extern std::string SetCommandLineOptionWithMode(const char* name, const char* value,
-                                           FlagSettingMode set_mode);
+extern GFLAGS_DLL_DECL std::string SetCommandLineOption        (const char* name, const char* value);
+extern GFLAGS_DLL_DECL std::string SetCommandLineOptionWithMode(const char* name, const char* value, FlagSettingMode set_mode);
 
 
 // --------------------------------------------------------------------
@@ -262,8 +264,8 @@ extern std::string SetCommandLineOptionWithMode(const char* name, const char* va
 //     // without worrying about restoring the FLAG values.
 //   }
 //
-// Note: This class is marked with ATTRIBUTE_UNUSED because all the
-// work is done in the constructor and destructor, so in the standard
+// Note: This class is marked with GFLAGS_ATTRIBUTE_UNUSED because all
+// the work is done in the constructor and destructor, so in the standard
 // usage example above, the compiler would complain that it's an
 // unused variable.
 //
@@ -282,27 +284,23 @@ class GFLAGS_DLL_DECL FlagSaver {
 
   FlagSaver(const FlagSaver&);  // no copying!
   void operator=(const FlagSaver&);
-}
-#ifndef _MSC_VER
-__attribute__ ((unused))
-#endif
-;
+};
 
 // --------------------------------------------------------------------
 // Some deprecated or hopefully-soon-to-be-deprecated functions.
 
 // This is often used for logging.  TODO(csilvers): figure out a better way
-extern std::string CommandlineFlagsIntoString();
+extern GFLAGS_DLL_DECL std::string CommandlineFlagsIntoString();
 // Usually where this is used, a FlagSaver should be used instead.
-extern bool ReadFlagsFromString(const std::string& flagfilecontents,
-                                const char* prog_name,
-                                bool errors_are_fatal);  // uses SET_FLAGS_VALUE
+extern GFLAGS_DLL_DECL
+bool ReadFlagsFromString(const std::string& flagfilecontents,
+                         const char* prog_name,
+                         bool errors_are_fatal);  // uses SET_FLAGS_VALUE
 
 // These let you manually implement --flagfile functionality.
 // DEPRECATED.
-extern bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
-extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name,
-                              bool errors_are_fatal);   // uses SET_FLAGS_VALUE
+extern GFLAGS_DLL_DECL bool AppendFlagsIntoFile(const std::string& filename, const char* prog_name);
+extern GFLAGS_DLL_DECL bool ReadFromFlagsFile(const std::string& filename, const char* prog_name, bool errors_are_fatal);   // uses SET_FLAGS_VALUE
 
 
 // --------------------------------------------------------------------
@@ -313,12 +311,12 @@ extern bool ReadFromFlagsFile(const std::string& filename, const char* prog_name
 // Otherwise, return the value.  NOTE: for booleans, for true use
 // 't' or 'T' or 'true' or '1', for false 'f' or 'F' or 'false' or '0'.
 
-extern bool BoolFromEnv(const char *varname, bool defval);
-extern int32 Int32FromEnv(const char *varname, int32 defval);
-extern int64 Int64FromEnv(const char *varname, int64 defval);
-extern uint64 Uint64FromEnv(const char *varname, uint64 defval);
-extern double DoubleFromEnv(const char *varname, double defval);
-extern const char *StringFromEnv(const char *varname, const char *defval);
+extern GFLAGS_DLL_DECL bool BoolFromEnv(const char *varname, bool defval);
+extern GFLAGS_DLL_DECL int32 Int32FromEnv(const char *varname, int32 defval);
+extern GFLAGS_DLL_DECL int64 Int64FromEnv(const char *varname, int64 defval);
+extern GFLAGS_DLL_DECL uint64 Uint64FromEnv(const char *varname, uint64 defval);
+extern GFLAGS_DLL_DECL double DoubleFromEnv(const char *varname, double defval);
+extern GFLAGS_DLL_DECL const char *StringFromEnv(const char *varname, const char *defval);
 
 
 // --------------------------------------------------------------------
@@ -330,12 +328,12 @@ extern const char *StringFromEnv(const char *varname, const char *defval);
 //   SetUsageMessage(usage);
 // Do not include commandline flags in the usage: we do that for you!
 // Thread-hostile; meant to be called before any threads are spawned.
-extern void SetUsageMessage(const std::string& usage);
+extern GFLAGS_DLL_DECL void SetUsageMessage(const std::string& usage);
 
 // Sets the version string, which is emitted with --version.
 // For instance: SetVersionString("1.3");
 // Thread-hostile; meant to be called before any threads are spawned.
-extern void SetVersionString(const std::string& version);
+extern GFLAGS_DLL_DECL void SetVersionString(const std::string& version);
 
 
 // Looks for flags in argv and parses them.  Rearranges argv to put
@@ -345,7 +343,7 @@ extern void SetVersionString(const std::string& version);
 // of the first non-flag argument.
 // See top-of-file for more details on this function.
 #ifndef SWIG   // In swig, use ParseCommandLineFlagsScript() instead.
-extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
+extern GFLAGS_DLL_DECL uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
 #endif
 
 
@@ -359,18 +357,18 @@ extern uint32 ParseCommandLineFlags(int *argc, char*** argv, bool remove_flags);
 // defined more than once in the command line or flag file, the last
 // definition is used.  Returns the index (into argv) of the first
 // non-flag argument.  (If remove_flags is true, will always return 1.)
-extern uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv,
-                                           bool remove_flags);
+extern GFLAGS_DLL_DECL uint32 ParseCommandLineNonHelpFlags(int *argc, char*** argv, bool remove_flags);
+
 // This is actually defined in gflags_reporting.cc.
 // This function is misnamed (it also handles --version, etc.), but
 // it's too late to change that now. :-(
-extern void HandleCommandLineHelpFlags();   // in gflags_reporting.cc
+extern GFLAGS_DLL_DECL void HandleCommandLineHelpFlags();   // in gflags_reporting.cc
 
 // Allow command line reparsing.  Disables the error normally
 // generated when an unknown flag is found, since it may be found in a
 // later parse.  Thread-hostile; meant to be called before any threads
 // are spawned.
-extern void AllowCommandLineReparsing();
+extern GFLAGS_DLL_DECL void AllowCommandLineReparsing();
 
 // Reparse the flags that have not yet been recognized.  Only flags
 // registered since the last parse will be recognized.  Any flag value
@@ -378,7 +376,7 @@ extern void AllowCommandLineReparsing();
 // separate command line argument that follows the flag argument.
 // Intended for handling flags from dynamically loaded libraries,
 // since their flags are not registered until they are loaded.
-extern void ReparseCommandLineNonHelpFlags();
+extern GFLAGS_DLL_DECL void ReparseCommandLineNonHelpFlags();
 
 // Clean up memory allocated by flags.  This is only needed to reduce
 // the quantity of "potentially leaked" reports emitted by memory
@@ -389,7 +387,7 @@ extern void ReparseCommandLineNonHelpFlags();
 // called will have unexpected consequences.  This is not safe to run
 // when multiple threads might be running: the function is
 // thread-hostile.
-extern void ShutDownCommandLineFlags();
+extern GFLAGS_DLL_DECL void ShutDownCommandLineFlags();
 
 
 // --------------------------------------------------------------------
@@ -420,7 +418,7 @@ extern void ShutDownCommandLineFlags();
 // directly.  The idea is that DEFINE puts the flag in the weird
 // namespace, and DECLARE imports the flag from there into the current
 // namespace.  The net result is to force people to use DECLARE to get
-// access to a flag, rather than saying "extern bool FLAGS_whatever;"
+// access to a flag, rather than saying "extern GFLAGS_DLL_DECL bool FLAGS_whatever;"
 // or some such instead.  We want this so we can put extra
 // functionality (like sanity-checking) in DECLARE if we want, and
 // make sure it is picked up everywhere.
@@ -441,16 +439,18 @@ class GFLAGS_DLL_DECL FlagRegisterer {
 // binary file. This can reduce the size of the resulting binary
 // somewhat, and may also be useful for security reasons.
 
-extern const char kStrippedFlagHelp[];
+extern GFLAGS_DLL_DECL const char kStrippedFlagHelp[];
+
+
+} // namespace gflags
 
-}
 
 #ifndef SWIG  // In swig, ignore the main flag declarations
 
 #if defined(STRIP_FLAG_HELP) && STRIP_FLAG_HELP > 0
 // Need this construct to avoid the 'defined but not used' warning.
 #define MAYBE_STRIPPED_HELP(txt) \
-   (false ? (txt) : ::google::kStrippedFlagHelp)
+   (false ? (txt) : gflags::kStrippedFlagHelp)
 #else
 #define MAYBE_STRIPPED_HELP(txt) txt
 #endif
@@ -472,7 +472,7 @@ extern const char kStrippedFlagHelp[];
     /* We always want to export defined variables, dll or no */         \
     GFLAGS_DLL_DEFINE_FLAG type FLAGS_##name = FLAGS_nono##name;        \
     type FLAGS_no##name = FLAGS_nono##name;                             \
-    static ::google::FlagRegisterer o_##name( \
+    static gflags::FlagRegisterer o_##name( \
       #name, #type, MAYBE_STRIPPED_HELP(help), __FILE__,                \
       &FLAGS_##name, &FLAGS_no##name);                                  \
   }                                                                     \
@@ -505,15 +505,15 @@ GFLAGS_DLL_DECL bool IsBoolFlag(bool from);
   DEFINE_VARIABLE(bool, B, name, val, txt)
 
 #define DEFINE_int32(name, val, txt) \
-   DEFINE_VARIABLE(::google::int32, I, \
+   DEFINE_VARIABLE(gflags::int32, I, \
                    name, val, txt)
 
 #define DEFINE_int64(name, val, txt) \
-   DEFINE_VARIABLE(::google::int64, I64, \
+   DEFINE_VARIABLE(gflags::int64, I64, \
                    name, val, txt)
 
 #define DEFINE_uint64(name,val, txt) \
-   DEFINE_VARIABLE(::google::uint64, U64, \
+   DEFINE_VARIABLE(gflags::uint64, U64, \
                    name, val, txt)
 
 #define DEFINE_double(name, val, txt) \
@@ -554,7 +554,7 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
     clstring* const FLAGS_no##name = ::fLS::                                \
                                    dont_pass0toDEFINE_string(s_##name[0].s, \
                                                              val);          \
-    static ::google::FlagRegisterer o_##name(  \
+    static gflags::FlagRegisterer o_##name(                       \
         #name, "string", MAYBE_STRIPPED_HELP(txt), __FILE__,                \
         s_##name[0].s, new (s_##name[1].s) clstring(*FLAGS_no##name));      \
     extern GFLAGS_DLL_DEFINE_FLAG clstring& FLAGS_##name;                   \
@@ -565,4 +565,4 @@ inline clstring* dont_pass0toDEFINE_string(char *stringspot,
 
 #endif  // SWIG
 
-#endif  // BASE_COMMANDLINEFLAGS_H_
+#endif  // GFLAGS_GFLAGS_H_
index 37f5b0ec2cfc406e0344c2b978acb4f87db0b7c9..2fa0db6d48af4b4ba8fd758eccbeb599638f0e50 100644 (file)
@@ -109,22 +109,13 @@ $ complete -o bashdefault -o default -o nospace -C                            \
 // produce the expected completion output.
 
 
-#ifndef BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
-#define BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#ifndef GFLAGS_COMPLETIONS_H_
+#define GFLAGS_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.
-//
-#define GFLAGS_DLL_DECL  /* rewritten to be non-empty in windows dir */
-
-
-namespace google {
+namespace gflags {
 
 extern void HandleCommandLineCompletions(void);
 
 }
 
-#endif  // BASE_COMMANDLINEFLAGS_COMPLETIONS_H_
+#endif  // GFLAGS_COMPLETIONS_H_
index 503b686657ffd0559977f7e790a9698803b3cb45..c390d30332b3ccc822570afd526caf9f779115ba 100644 (file)
 // This is the file that should be included by any file which declares
 // command line flag.
 
-#ifndef BASE_COMMANDLINEFLAGS_DECLARE_H_
-#define BASE_COMMANDLINEFLAGS_DECLARE_H_
-
-#include <string>
-#if 1
-#include <stdint.h>         // the normal place uint16_t is defined
+#ifndef GFLAGS_DECLARE_H_
+#define GFLAGS_DECLARE_H_
+
+// ---------------------------------------------------------------------------
+// Windows DLL import/export.
+
+// We always want to import the symbols of the gflags library
+#ifndef GFLAGS_DLL_DECL
+#  if 1 && defined(_MSC_VER)
+#    define GFLAGS_DLL_DECL __declspec(dllimport)
+#  else
+#    define GFLAGS_DLL_DECL
+#  endif
 #endif
-#if 1
-#include <sys/types.h>      // the normal place u_int16_t is defined
+
+// We always want to import variables declared in user code
+#ifndef GFLAGS_DLL_DECLARE_FLAG
+#  ifdef _MSC_VER
+#    define GFLAGS_DLL_DECLARE_FLAG __declspec(dllimport)
+#  else
+#    define GFLAGS_DLL_DECLARE_FLAG
+#  endif
 #endif
+
+// ---------------------------------------------------------------------------
+// Flag types
+#include <string>
 #if 1
-#include <inttypes.h>       // a third place for uint16_t or u_int16_t
+#  include <stdint.h>                   // the normal place uint32_t is defined
+#elif 1
+#  include <sys/types.h>                // the normal place u_int32_t is defined
+#elif 1
+#  include <inttypes.h>                 // a third place for uint32_t or u_int32_t
 #endif
 
-namespace google {
-#if defined(__GNUC__) || defined(__MINGW32__)      // the C99 format
-typedef int32_t int32;
-typedef uint32_t uint32;
-typedef int64_t int64;
-typedef uint64_t uint64;
-#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)   // the BSD format
-typedef int32_t int32;
-typedef u_int32_t uint32;
-typedef int64_t int64;
-typedef u_int64_t uint64;
-#elif defined(_MSC_VER)     // the windows (vc7) format
-typedef __int32 int32;
+namespace gflags {
+
+#if 1 // C99
+typedef int32_t          int32;
+typedef uint32_t         uint32;
+typedef int64_t          int64;
+typedef uint64_t         uint64;
+#elif 0 // BSD
+typedef int32_t          int32;
+typedef u_int32_t        uint32;
+typedef int64_t          int64;
+typedef u_int64_t        uint64;
+#elif 0 // Windows
+typedef __int32          int32;
 typedef unsigned __int32 uint32;
-typedef __int64 int64;
+typedef __int64          int64;
 typedef unsigned __int64 uint64;
 #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
-}
 
+} // namespace gflags
 
-#define GFLAGS_DLL_DECLARE_FLAG  /* rewritten to be non-empty in windows dir */
 
 namespace fLS {
 
@@ -80,7 +101,8 @@ namespace fLS {
 // included).  Save the current meaning now and use it in the macros.
 typedef std::string clstring;
 
-}
+} // namespace fLS
+
 
 #define DECLARE_VARIABLE(type, shorttype, name) \
   /* We always want to import declared variables, dll or no */ \
@@ -91,22 +113,24 @@ typedef std::string clstring;
   DECLARE_VARIABLE(bool, B, name)
 
 #define DECLARE_int32(name) \
-  DECLARE_VARIABLE(::google::int32, I, name)
+  DECLARE_VARIABLE(::gflags::int32, I, name)
 
 #define DECLARE_int64(name) \
-  DECLARE_VARIABLE(::google::int64, I64, name)
+  DECLARE_VARIABLE(::gflags::int64, I64, name)
 
 #define DECLARE_uint64(name) \
-  DECLARE_VARIABLE(::google::uint64, U64, name)
+  DECLARE_VARIABLE(::gflags::uint64, U64, name)
 
 #define DECLARE_double(name) \
   DECLARE_VARIABLE(double, D, name)
 
 #define DECLARE_string(name) \
-  namespace fLS {                       \
-  using ::fLS::clstring;                \
+  /* We always want to import declared variables, dll or no */ \
+  namespace fLS { \
+  using ::fLS::clstring; \
   extern GFLAGS_DLL_DECLARE_FLAG ::fLS::clstring& FLAGS_##name; \
-  }                                     \
+  } \
   using fLS::FLAGS_##name
 
-#endif  // BASE_COMMANDLINEFLAGS_DECLARE_H_
+
+#endif  // GFLAGS_DECLARE_H_
index f46a2e0814ec4bf2c5282be7cbca3581572da4f8..3a476230ff974b2fa9e42ce877dcd8ab5d9f004c 100644 (file)
@@ -48,6 +48,7 @@
 
 
 #include "config.h"
+
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>   // for strlen
 #include <utility>
 #include <vector>
 
-#include "gflags/gflags_completions.h"
-#include "gflags/gflags.h"
+#include "gflags.h"
 #include "util.h"
 
 using std::set;
 using std::string;
 using std::vector;
 
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR  '/'
-#endif
 
 DEFINE_string(tab_completion_word, "",
               "If non-empty, HandleCommandLineCompletions() will hijack the "
@@ -76,7 +73,9 @@ DEFINE_string(tab_completion_word, "",
 DEFINE_int32(tab_completion_columns, 80,
              "Number of columns to use in output for tab completion");
 
-_START_GOOGLE_NAMESPACE_
+
+namespace GFLAGS_NAMESPACE {
+
 
 namespace {
 // Function prototypes and Type forward declarations.  Code may be
@@ -766,4 +765,5 @@ void HandleCommandLineCompletions(void) {
   gflags_exitfunc(0);
 }
 
-_END_GOOGLE_NAMESPACE_
+
+} // namespace GFLAGS_NAMESPACE
index c74bcc8d762dfb6771ba0820f2c70e031a54629f..9cc41a7488ce5dcfd04c94431ee473b87b5a381d 100644 (file)
 // called after all flag-values have been assigned, that is, after
 // parsing the command-line.
 
-#include "config.h"
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
 #include <assert.h>
 #include <string>
 #include <vector>
-#include "gflags/gflags.h"
-#include "gflags/gflags_completions.h"
+
+#include "config.h"
+#include "gflags.h"
+#include "gflags_completions.h"
 #include "util.h"
 
-#ifndef PATH_SEPARATOR
-#define PATH_SEPARATOR  '/'
-#endif
 
 // 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,
-            "show help on all flags -- same as -help");
-DEFINE_bool(helpshort, false,
-            "show help on only the main module for this program");
-DEFINE_string(helpon, "",
-              "show help on the modules named by this flag value");
-DEFINE_string(helpmatch, "",
-              "show help on modules whose name contains the specified substr");
-DEFINE_bool(helppackage, false,
-            "show help on all modules in the main package");
-DEFINE_bool(helpxml, false,
-            "produce an xml version of help");
-DEFINE_bool(version, false,
-            "show version and build info and exit");
-
-_START_GOOGLE_NAMESPACE_
+DEFINE_bool  (help,        false, "show help on all flags [tip: all flags can have two dashes]");
+DEFINE_bool  (helpfull,    false, "show help on all flags -- same as -help");
+DEFINE_bool  (helpshort,   false, "show help on only the main module for this program");
+DEFINE_string(helpon,      "",    "show help on the modules named by this flag value");
+DEFINE_string(helpmatch,   "",    "show help on modules whose name contains the specified substr");
+DEFINE_bool  (helppackage, false, "show help on all modules in the main package");
+DEFINE_bool  (helpxml,     false, "produce an xml version of help");
+DEFINE_bool  (version,     false, "show version and build info and exit");
+
+
+namespace GFLAGS_NAMESPACE {
+
 
 using std::string;
 using std::vector;
@@ -254,7 +246,7 @@ static bool FileMatchesSubstring(const string& filename,
     // the string to be at the beginning of a directory component.
     // That should match the first directory component as well, so
     // we allow '/foo' to match a filename of 'foo'.
-    if (!target->empty() && (*target)[0] == '/' &&
+    if (!target->empty() && (*target)[0] == PATH_SEPARATOR &&
         strncmp(filename.c_str(), target->c_str() + 1,
                 strlen(target->c_str() + 1)) == 0)
       return true;
@@ -360,7 +352,8 @@ static void ShowVersion() {
 
 static void AppendPrognameStrings(vector<string>* substrings,
                                   const char* progname) {
-  string r("/");
+  string r("");
+  r += PATH_SEPARATOR;
   r += progname;
   substrings->push_back(r + ".");
   substrings->push_back(r + "-main.");
@@ -395,7 +388,7 @@ void HandleCommandLineHelpFlags() {
     gflags_exitfunc(1);
 
   } else if (!FLAGS_helpon.empty()) {
-    string restrict = "/" + FLAGS_helpon + ".";
+    string restrict = PATH_SEPARATOR + FLAGS_helpon + ".";
     ShowUsageWithFlagsRestrict(progname, restrict.c_str());
     gflags_exitfunc(1);
 
@@ -417,7 +410,7 @@ void HandleCommandLineHelpFlags() {
          ++flag) {
       if (!FileMatchesSubstring(flag->filename, substrings))
         continue;
-      const string package = Dirname(flag->filename) + "/";
+      const string package = Dirname(flag->filename) + PATH_SEPARATOR;
       if (package != last_package) {
         ShowUsageWithFlagsRestrict(progname, package.c_str());
         VLOG(7) << "Found package: " << package;
@@ -444,4 +437,5 @@ void HandleCommandLineHelpFlags() {
   }
 }
 
-_END_GOOGLE_NAMESPACE_
+
+} // namespace GFLAGS_NAMESPACE
index 7c3c060a043478a6284b8a1e8a2a9f1e9255ae33..0bdd9d5f2a5c8c57dddec434a560367aaef103bf 100644 (file)
 // A simple mutex wrapper, supporting locks and read-write locks.
 // You should assume the locks are *not* re-entrant.
 //
-// To use: you should define the following macros in your configure.ac:
-//   ACX_PTHREAD
-//   AC_RWLOCK
-// The latter is defined in ../autoconf.
-//
 // This class is meant to be internal-only and should be wrapped by an
 // internal namespace.  Before you use this module, please give the
 // name of your internal namespace for this module.  Or, if you want
 // weird to a Mutex's memory after it is destroyed, but for a
 // static global variable, that's pretty safe.
 
-#ifndef GOOGLE_MUTEX_H_
-#define GOOGLE_MUTEX_H_
+#ifndef GFLAGS_MUTEX_H_
+#define GFLAGS_MUTEX_H_
 
-#include "config.h"           // to figure out pthreads support
+#include "gflags_declare.h"     // to figure out pthreads support
 
 #if defined(NO_THREADS)
-  typedef int MutexType;      // to keep a lock-count
-#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+  typedef int MutexType;        // to keep a lock-count
+#elif defined(OS_WINDOWS)
 # ifndef WIN32_LEAN_AND_MEAN
 #   define WIN32_LEAN_AND_MEAN  // We only need minimal includes
 # endif
@@ -232,7 +227,7 @@ bool Mutex::TryLock()      { if (mutex_) return false; Lock(); return true; }
 void Mutex::ReaderLock()   { assert(++mutex_ > 0); }
 void Mutex::ReaderUnlock() { assert(mutex_-- > 0); }
 
-#elif defined(_WIN32) || defined(__CYGWIN32__) || defined(__CYGWIN64__)
+#elif defined(OS_WINDOWS)
 
 Mutex::Mutex() : destroy_(true) {
   InitializeCriticalSection(&mutex_);
@@ -353,4 +348,4 @@ using namespace MUTEX_NAMESPACE;
 
 #undef MUTEX_NAMESPACE
 
-#endif  /* #define GOOGLE_MUTEX_H__ */
+#endif  /* #define GFLAGS_MUTEX_H__ */
index 8e2b1b8952583b15bfb153803e4f43f1a3c07b20..366e1be22e2e1d3038187f7af26bc0af36b158a0 100644 (file)
 #ifndef GFLAGS_UTIL_H_
 #define GFLAGS_UTIL_H_
 
-#include <assert.h>
 #include "config.h"
+
+#include <assert.h>
+#include <config.h>
 #ifdef HAVE_INTTYPES_H
-# include <inttypes.h>
+#  include <inttypes.h>
 #endif
 #include <stdarg.h>     // for va_*
 #include <stdlib.h>
 #include <stdio.h>
 #include <iostream>
 #include <string>
+#include <errno.h>
 #ifdef HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif   // for mkdir()
+#  include <sys/stat.h> // for mkdir
+#endif
+
+
+namespace GFLAGS_NAMESPACE {
 
-_START_GOOGLE_NAMESPACE_
 
 // This is used for unittests for death-testing.  It is defined in gflags.cc.
 extern GFLAGS_DLL_DECL void (*gflags_exitfunc)(int);
 
-// Work properly if either strtoll or strtoq is on this system
-#ifdef HAVE_STRTOLL
-# define strto64  strtoll
-# define strtou64  strtoull
-#elif HAVE_STRTOQ
-# define strto64  strtoq
-# define strtou64  strtouq
-#else
+// Work properly if either strtoll or strtoq is on this system.
+#if defined(strtoll) || defined(HAVE_STRTOLL)
+#  define strto64  strtoll
+#  define strtou64 strtoull
+#elif defined(HAVE_STRTOQ)
+#  define strto64  strtoq
+#  define strtou64 strtouq
 // Neither strtoll nor strtoq are defined.  I hope strtol works!
-# define strto64 strtol
-# define strtou64 strtoul
+#else
+#  define strto64  strtol
+#  define strtou64 strtoul
 #endif
 
-// If we have inttypes.h, it will have defined PRId32/etc for us.  If
-// not, take our best guess.
+// If we have inttypes.h, it will have defined PRId32/etc for us.
+// If not, take our best guess.
 #ifndef PRId32
-# define PRId32 "d"
+#  define PRId32 "d"
 #endif
 #ifndef PRId64
-# define PRId64 "lld"
+#  define PRId64 "lld"
 #endif
 #ifndef PRIu64
-# define PRIu64 "llu"
+#  define PRIu64 "llu"
 #endif
 
 typedef signed char int8;
@@ -230,37 +235,36 @@ class Test {};
 #if defined(__MINGW32__)
 #include <io.h>
 inline void MakeTmpdir(std::string* path) {
+  if (!path->empty()) {
+       path->append("/gflags_unittest_testdir");
+       int err = mkdir(path->c_str());
+       if (err == 0 || errno == EEXIST) return;
+  }
   // I had trouble creating a directory in /tmp from mingw
-  *path = "./gflags_unittest_testdir";
-  mkdir(path->c_str());   // mingw has a weird one-arg mkdir
+  *path = "./gflags_unittest";
+  mkdir(path->c_str());
 }
 #elif defined(_MSC_VER)
 #include <direct.h>
-#include <windows.h>
 inline void MakeTmpdir(std::string* path) {
+  if (!path->empty()) {
+       int err = _mkdir(path->c_str());
+       if (err == 0 || errno == EEXIST) return;
+  }
   char tmppath_buffer[1024];
   int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
   assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer));
   assert(tmppath_buffer[tmppath_len - 1] == '\\');   // API guarantees it
-  *path = std::string(tmppath_buffer) + "gflags_unittest_testdir";
+  *path = std::string(tmppath_buffer) + "gflags_unittest";
   _mkdir(path->c_str());
 }
-// Windows is missing random bits like strcasecmp, strtoll, strtoull, and
-// snprintf in the usual locations. Put them somewhere sensible.
-//
-// TODO(keir): Get the upstream Windows port and use that instead.
-#define snprintf _snprintf
-#undef strtoint64
-#define strtoint64 _strtoi64
-#undef strtouint64
-#define strtouint64 _strtoui64
-#define strcasecmp _stricmp
-#define va_copy(dst, src) ((dst) = (src))
-#define strto64 _strtoi64
-#define strtou64 _strtoui64
 #else
 inline void MakeTmpdir(std::string* path) {
-  mkdir(path->c_str(), 0755);
+  if (!path->empty()) {
+       int err = mkdir(path->c_str(), 0755);
+       if (err == 0 || errno == EEXIST) return;
+  }
+  mkdir("/tmp/gflags_unittest", 0755);
 }
 #endif
 
@@ -278,7 +282,7 @@ inline void InternalStringPrintf(std::string* output, const char* format,
   int bytes_written = vsnprintf(space, sizeof(space), format, backup_ap);
   va_end(backup_ap);
 
-  if ((bytes_written >= 0) && (bytes_written < sizeof(space))) {
+  if ((bytes_written >= 0) && (static_cast<size_t>(bytes_written) < sizeof(space))) {
     output->append(space, bytes_written);
     return;
   }
@@ -334,6 +338,36 @@ inline std::string StringPrintf(const char* format, ...) {
   return output;
 }
 
-_END_GOOGLE_NAMESPACE_
+inline bool SafeGetEnv(const char *varname, std::string &valstr)
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+       char  *val;
+       size_t sz;
+       if (_dupenv_s(&val, &sz, varname) != 0 || !val) return false;
+       valstr = val;
+       free(val);
+#else
+       const char * const val = getenv(varname);
+       if (!val) return false;
+       valstr = val;
+#endif
+       return true;
+}
+
+inline int SafeFOpen(FILE **fp, const char* fname, const char *mode)
+{
+#if defined(_MSC_VER) && _MSC_VER >= 1400
+       return fopen_s(fp, fname, mode);
+#else
+       assert(fp != NULL);
+       *fp = fopen(fname, mode);
+    // errno only guaranteed to be set on failure
+       return ((*fp == NULL) ? errno : 0);
+#endif
+}
+
+
+} // namespace GFLAGS_NAMESPACE
+
 
 #endif  // GFLAGS_UTIL_H_
index eb4b2ea337989a901fde12a12979a07a67852f00..10e51fa6df408826f7ff1dd6cf4af40b2c79fc79 100644 (file)
@@ -1,7 +1,7 @@
 Project: Google Logging
 URL: http://code.google.com/p/google-glog/
 License: New BSD
-Upstream version: 0.3.3, r139
+Upstream version: 0.3.3, r143
 Local modifications:
 * Added per-platform config.h files so no configuration-time
   checks for functions and so are needed.
index 0daf30893b356a963ab7d81b0a06f9e4d5f33a28..e858181a68f4ec83b4a3e30e71ba13c5bb082cd8 100644 (file)
@@ -167,7 +167,7 @@ static size_t StrLen(const char *str) {
 // Returns true if "str" has at least "n" characters remaining.
 static bool AtLeastNumCharsRemaining(const char *str, int n) {
   for (int i = 0; i < n; ++i) {
-    if (str == '\0') {
+    if (str[i] == '\0') {
       return false;
     }
   }
@@ -223,9 +223,6 @@ static bool ParseTwoCharToken(State *state, const char *two_char_token) {
 // Returns true and advances "mangled_cur" if we find any character in
 // "char_class" at "mangled_cur" position.
 static bool ParseCharClass(State *state, const char *char_class) {
-  if (state->mangled_cur == '\0') {
-    return false;
-  }
   const char *p = char_class;
   for (; *p != '\0'; ++p) {
     if (state->mangled_cur[0] == *p) {
index 5e2ce61c9c9f64fd98a02fb65809c92b89faef94..75047353535bb06f5b07db9348ea4f5e4f67c052 100644 (file)
@@ -31,6 +31,7 @@
 
 #include "utilities.h"
 
+#include <algorithm>
 #include <assert.h>
 #include <iomanip>
 #include <string>
@@ -181,6 +182,10 @@ GLOG_DEFINE_string(log_backtrace_at, "",
 #define PATH_SEPARATOR '/'
 
 #ifndef HAVE_PREAD
+#if defined(OS_WINDOWS)
+#include <BaseTsd.h>
+#define ssize_t SSIZE_T
+#endif
 static ssize_t pread(int fd, void* buf, size_t count, off_t offset) {
   off_t orig_offset = lseek(fd, 0, SEEK_CUR);
   if (orig_offset == (off_t)-1)
index 18bbccf307213d5257c51205e08ff37095608259..b25f7479d0df09f0c9dd87637df1a929124fed41 100644 (file)
 // some functions which are not guaranteed to be so, such as memchr()
 // and memmove().  We assume they are async-signal-safe.
 //
+// Additional header can be specified by the GLOG_BUILD_CONFIG_INCLUDE
+// macro to add platform specific defines (e.g. OS_OPENBSD).
+
+#ifdef GLOG_BUILD_CONFIG_INCLUDE
+#include GLOG_BUILD_CONFIG_INCLUDE
+#endif  // GLOG_BUILD_CONFIG_INCLUDE
 
 #include "utilities.h"
 
@@ -74,6 +80,13 @@ void InstallSymbolizeCallback(SymbolizeCallback callback) {
   g_symbolize_callback = callback;
 }
 
+static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
+    NULL;
+void InstallSymbolizeOpenObjectFileCallback(
+    SymbolizeOpenObjectFileCallback callback) {
+  g_symbolize_open_object_file_callback = callback;
+}
+
 // This function wraps the Demangle function to provide an interface
 // where the input symbol is demangled in-place.
 // To keep stack consumption low, we would like this function to not
@@ -95,11 +108,14 @@ _END_GOOGLE_NAMESPACE_
 #if defined(__ELF__)
 
 #include <dlfcn.h>
+#if defined(OS_OPENBSD)
+#include <sys/exec_elf.h>
+#else
 #include <elf.h>
+#endif
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
-#include <link.h>  // For ElfW() macro.
 #include <stdint.h>
 #include <stdio.h>
 #include <stdlib.h>
@@ -123,7 +139,7 @@ _START_GOOGLE_NAMESPACE_
 // success, return the number of bytes read.  Otherwise, return -1.
 static ssize_t ReadPersistent(const int fd, void *buf, const size_t count) {
   SAFE_ASSERT(fd >= 0);
-  SAFE_ASSERT(count >= 0 && count <= std::numeric_limits<ssize_t>::max());
+  SAFE_ASSERT(count <= std::numeric_limits<ssize_t>::max());
   char *buf0 = reinterpret_cast<char *>(buf);
   ssize_t num_bytes = 0;
   while (num_bytes < count) {
@@ -326,31 +342,29 @@ static bool GetSymbolFromObjectFile(const int fd, uint64_t pc,
   ElfW(Shdr) symtab, strtab;
 
   // Consult a regular symbol table first.
-  if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
-                              SHT_SYMTAB, &symtab)) {
-    return false;
-  }
-  if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
-                           symtab.sh_link * sizeof(symtab))) {
-    return false;
-  }
-  if (FindSymbol(pc, fd, out, out_size, symbol_offset,
-                 &strtab, &symtab)) {
-    return true;  // Found the symbol in a regular symbol table.
+  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+                             SHT_SYMTAB, &symtab)) {
+    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+                             symtab.sh_link * sizeof(symtab))) {
+      return false;
+    }
+    if (FindSymbol(pc, fd, out, out_size, symbol_offset,
+                   &strtab, &symtab)) {
+      return true;  // Found the symbol in a regular symbol table.
+    }
   }
 
   // If the symbol is not found, then consult a dynamic symbol table.
-  if (!GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
-                              SHT_DYNSYM, &symtab)) {
-    return false;
-  }
-  if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
-                           symtab.sh_link * sizeof(symtab))) {
-    return false;
-  }
-  if (FindSymbol(pc, fd, out, out_size, symbol_offset,
-                 &strtab, &symtab)) {
-    return true;  // Found the symbol in a dynamic symbol table.
+  if (GetSectionHeaderByType(fd, elf_header.e_shnum, elf_header.e_shoff,
+                             SHT_DYNSYM, &symtab)) {
+    if (!ReadFromOffsetExact(fd, &strtab, sizeof(strtab), elf_header.e_shoff +
+                             symtab.sh_link * sizeof(symtab))) {
+      return false;
+    }
+    if (FindSymbol(pc, fd, out, out_size, symbol_offset,
+                   &strtab, &symtab)) {
+      return true;  // Found the symbol in a dynamic symbol table.
+    }
   }
 
   return false;
@@ -481,13 +495,20 @@ static char *GetHex(const char *start, const char *end, uint64_t *hex) {
   return const_cast<char *>(p);
 }
 
-// Search for the object file (from /proc/self/maps) that contains
-// the specified pc. If found, open this file and return the file handle,
-// and also set start_address to the start address of where this object
-// file is mapped to in memory. Otherwise, return -1.
+// Searches for the object file (from /proc/self/maps) that contains
+// the specified pc.  If found, sets |start_address| to the start address
+// of where this object file is mapped in memory, sets the module base
+// address into |base_address|, copies the object file name into
+// |out_file_name|, and attempts to open the object file.  If the object
+// file is opened successfully, returns the file descriptor.  Otherwise,
+// returns -1.  |out_file_name_size| is the size of the file name buffer
+// (including the null-terminator).
 static ATTRIBUTE_NOINLINE int
 OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
-                                             uint64_t &start_address) {
+                                             uint64_t &start_address,
+                                             uint64_t &base_address,
+                                             char *out_file_name,
+                                             int out_file_name_size) {
   int object_fd;
 
   // Open /proc/self/maps.
@@ -501,8 +522,10 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
   // Iterate over maps and look for the map containing the pc.  Then
   // look into the symbol tables inside.
   char buf[1024];  // Big enough for line of sane /proc/self/maps
+  int num_maps = 0;
   LineReader reader(wrapped_maps_fd.get(), buf, sizeof(buf));
   while (true) {
+    num_maps++;
     const char *cursor;
     const char *eol;
     if (!reader.ReadLine(&cursor, &eol)) {  // EOF or malformed line.
@@ -552,14 +575,35 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
     }
     ++cursor;  // Skip ' '.
 
-    // Skip to file name.  "cursor" now points to file offset.  We need to
-    // skip at least three spaces for file offset, dev, and inode.
+    // Read file offset.
+    uint64_t file_offset;
+    cursor = GetHex(cursor, eol, &file_offset);
+    if (cursor == eol || *cursor != ' ') {
+      return -1;  // Malformed line.
+    }
+    ++cursor;  // Skip ' '.
+
+    // Don't subtract 'start_address' from the first entry:
+    // * If a binary is compiled w/o -pie, then the first entry in
+    //   process maps is likely the binary itself (all dynamic libs
+    //   are mapped higher in address space). For such a binary,
+    //   instruction offset in binary coincides with the actual
+    //   instruction address in virtual memory (as code section
+    //   is mapped to a fixed memory range).
+    // * If a binary is compiled with -pie, all the modules are
+    //   mapped high at address space (in particular, higher than
+    //   shadow memory of the tool), so the module can't be the
+    //   first entry.
+    base_address = ((num_maps == 1) ? 0U : start_address) - file_offset;
+
+    // Skip to file name.  "cursor" now points to dev.  We need to
+    // skip at least two spaces for dev and inode.
     int num_spaces = 0;
     while (cursor < eol) {
       if (*cursor == ' ') {
         ++num_spaces;
-      } else if (num_spaces >= 3) {
-        // The first non-space character after  skipping three spaces
+      } else if (num_spaces >= 2) {
+        // The first non-space character after skipping two spaces
         // is the beginning of the file name.
         break;
       }
@@ -572,12 +616,105 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
     // Finally, "cursor" now points to file name of our interest.
     NO_INTR(object_fd = open(cursor, O_RDONLY));
     if (object_fd < 0) {
+      // Failed to open object file.  Copy the object file name to
+      // |out_file_name|.
+      strncpy(out_file_name, cursor, out_file_name_size);
+      // Making sure |out_file_name| is always null-terminated.
+      out_file_name[out_file_name_size - 1] = '\0';
       return -1;
     }
     return object_fd;
   }
 }
 
+// POSIX doesn't define any async-signal safe function for converting
+// an integer to ASCII. We'll have to define our own version.
+// itoa_r() converts a (signed) integer to ASCII. It returns "buf", if the
+// conversion was successful or NULL otherwise. It never writes more than "sz"
+// bytes. Output will be truncated as needed, and a NUL character is always
+// appended.
+// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
+char *itoa_r(intptr_t i, char *buf, size_t sz, int base, size_t padding) {
+  // Make sure we can write at least one NUL byte.
+  size_t n = 1;
+  if (n > sz)
+    return NULL;
+
+  if (base < 2 || base > 16) {
+    buf[0] = '\000';
+    return NULL;
+  }
+
+  char *start = buf;
+
+  uintptr_t j = i;
+
+  // Handle negative numbers (only for base 10).
+  if (i < 0 && base == 10) {
+    j = -i;
+
+    // Make sure we can write the '-' character.
+    if (++n > sz) {
+      buf[0] = '\000';
+      return NULL;
+    }
+    *start++ = '-';
+  }
+
+  // Loop until we have converted the entire number. Output at least one
+  // character (i.e. '0').
+  char *ptr = start;
+  do {
+    // Make sure there is still enough space left in our output buffer.
+    if (++n > sz) {
+      buf[0] = '\000';
+      return NULL;
+    }
+
+    // Output the next digit.
+    *ptr++ = "0123456789abcdef"[j % base];
+    j /= base;
+
+    if (padding > 0)
+      padding--;
+  } while (j > 0 || padding > 0);
+
+  // Terminate the output with a NUL character.
+  *ptr = '\000';
+
+  // Conversion to ASCII actually resulted in the digits being in reverse
+  // order. We can't easily generate them in forward order, as we can't tell
+  // the number of characters needed until we are done converting.
+  // So, now, we reverse the string (except for the possible "-" sign).
+  while (--ptr > start) {
+    char ch = *ptr;
+    *ptr = *start;
+    *start++ = ch;
+  }
+  return buf;
+}
+
+// Safely appends string |source| to string |dest|.  Never writes past the
+// buffer size |dest_size| and guarantees that |dest| is null-terminated.
+void SafeAppendString(const char* source, char* dest, int dest_size) {
+  int dest_string_length = strlen(dest);
+  SAFE_ASSERT(dest_string_length < dest_size);
+  dest += dest_string_length;
+  dest_size -= dest_string_length;
+  strncpy(dest, source, dest_size);
+  // Making sure |dest| is always null-terminated.
+  dest[dest_size - 1] = '\0';
+}
+
+// Converts a 64-bit value into a hex string, and safely appends it to |dest|.
+// Never writes past the buffer size |dest_size| and guarantees that |dest| is
+// null-terminated.
+void SafeAppendHexNumber(uint64_t value, char* dest, int dest_size) {
+  // 64-bit numbers in hex can have up to 16 digits.
+  char buf[17] = {'\0'};
+  SafeAppendString(itoa_r(value, buf, sizeof(buf), 16, 0), dest, dest_size);
+}
+
 // The implementation of our symbolization routine.  If it
 // successfully finds the symbol containing "pc" and obtains the
 // symbol name, returns true and write the symbol name to "out".
@@ -590,10 +727,40 @@ static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
                                                     int out_size) {
   uint64_t pc0 = reinterpret_cast<uintptr_t>(pc);
   uint64_t start_address = 0;
+  uint64_t base_address = 0;
+  int object_fd = -1;
 
-  int object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0,
-                                                               start_address);
-  if (object_fd == -1) {
+  if (out_size < 1) {
+    return false;
+  }
+  out[0] = '\0';
+  SafeAppendString("(", out, out_size);
+
+  if (g_symbolize_open_object_file_callback) {
+    object_fd = g_symbolize_open_object_file_callback(pc0, start_address,
+                                                      base_address, out + 1,
+                                                      out_size - 1);
+  } else {
+    object_fd = OpenObjectFileContainingPcAndGetStartAddress(pc0, start_address,
+                                                             base_address,
+                                                             out + 1,
+                                                             out_size - 1);
+  }
+
+  // Check whether a file name was returned.
+  if (object_fd < 0) {
+    if (out[1]) {
+      // The object file containing PC was determined successfully however the
+      // object file was not opened successfully.  This is still considered
+      // success because the object file name and offset are known and tools
+      // like asan_symbolize.py can be used for the symbolization.
+      out[out_size - 1] = '\0';  // Making sure |out| is always null-terminated.
+      SafeAppendString("+0x", out, out_size);
+      SafeAppendHexNumber(pc0 - base_address, out, out_size);
+      SafeAppendString(")", out, out_size);
+      return true;
+    }
+    // Failed to determine the object file containing PC.  Bail out.
     return false;
   }
   FileDescriptor wrapped_object_fd(object_fd);
index 1ebe4dd94a2540d5658de31345e340d86910e917..f617184249ce2f6334dce25c0a2a5cbc29b2c003 100644 (file)
 
 #ifdef HAVE_SYMBOLIZE
 
-#if defined(__ELF__)  // defined by gcc on Linux
+#if defined(__ELF__)  // defined by gcc
+#if defined(__OpenBSD__)
+#include <sys/exec_elf.h>
+#else
 #include <elf.h>
+#endif
+
+#if !defined(ANDROID)
 #include <link.h>  // For ElfW() macro.
+#endif
+
+// For systems where SIZEOF_VOID_P is not defined, determine it
+// based on __LP64__ (defined by gcc on 64-bit systems)
+#if !defined(SIZEOF_VOID_P)
+# if defined(__LP64__)
+#  define SIZEOF_VOID_P 8
+# else
+#  define SIZEOF_VOID_P 4
+# endif
+#endif
 
 // If there is no ElfW macro, let's define it by ourself.
 #ifndef ElfW
@@ -88,6 +105,10 @@ _END_GOOGLE_NAMESPACE_
 
 _START_GOOGLE_NAMESPACE_
 
+// Restrictions on the callbacks that follow:
+//  - The callbacks must not use heaps but only use stacks.
+//  - The callbacks must be async-signal-safe.
+
 // Installs a callback function, which will be called right before a symbol name
 // is printed. The callback is intended to be used for showing a file name and a
 // line number preceding a symbol name.
@@ -99,6 +120,24 @@ typedef int (*SymbolizeCallback)(int fd, void *pc, char *out, size_t out_size,
                                  uint64 relocation);
 void InstallSymbolizeCallback(SymbolizeCallback callback);
 
+// Installs a callback function, which will be called instead of
+// OpenObjectFileContainingPcAndGetStartAddress.  The callback is expected
+// to searches for the object file (from /proc/self/maps) that contains
+// the specified pc.  If found, sets |start_address| to the start address
+// of where this object file is mapped in memory, sets the module base
+// address into |base_address|, copies the object file name into
+// |out_file_name|, and attempts to open the object file.  If the object
+// file is opened successfully, returns the file descriptor.  Otherwise,
+// returns -1.  |out_file_name_size| is the size of the file name buffer
+// (including the null-terminator).
+typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc,
+                                               uint64_t &start_address,
+                                               uint64_t &base_address,
+                                               char *out_file_name,
+                                               int out_file_name_size);
+void InstallSymbolizeOpenObjectFileCallback(
+    SymbolizeOpenObjectFileCallback callback);
+
 _END_GOOGLE_NAMESPACE_
 
 #endif
index 9a3725745c20578c73118a359872fb377ae7d78f..24ec2b4aeddf46a5bae68aa92b8681489bb3d296 100644 (file)
@@ -33,10 +33,10 @@ void CCL_init_logging(const char *argv0)
                 google::GLOG_FATAL);
 
        google::InitGoogleLogging(argv0);
-       google::SetCommandLineOption("logtostderr", "1");
-       google::SetCommandLineOption("v", "0");
-       google::SetCommandLineOption("stderrthreshold", severity_fatal);
-       google::SetCommandLineOption("minloglevel", severity_fatal);
+       gflags::SetCommandLineOption("logtostderr", "1");
+       gflags::SetCommandLineOption("v", "0");
+       gflags::SetCommandLineOption("stderrthreshold", severity_fatal);
+       gflags::SetCommandLineOption("minloglevel", severity_fatal);
 #else
        (void) argv0;
 #endif
@@ -45,10 +45,10 @@ void CCL_init_logging(const char *argv0)
 void CCL_start_debug_logging(void)
 {
 #ifdef WITH_CYCLES_LOGGING
-       google::SetCommandLineOption("logtostderr", "1");
-       google::SetCommandLineOption("v", "2");
-       google::SetCommandLineOption("stderrthreshold", "1");
-       google::SetCommandLineOption("minloglevel", "0");
+       gflags::SetCommandLineOption("logtostderr", "1");
+       gflags::SetCommandLineOption("v", "2");
+       gflags::SetCommandLineOption("stderrthreshold", "1");
+       gflags::SetCommandLineOption("minloglevel", "0");
 #endif
 }
 
@@ -58,7 +58,7 @@ void CCL_logging_verbosity_set(int verbosity)
        char val[10];
        snprintf(val, sizeof(val), "%d", verbosity);
 
-       google::SetCommandLineOption("v", val);
+       gflags::SetCommandLineOption("v", val);
 #else
        (void) verbosity;
 #endif
index ef8e743b642fa3d820c1ef5dcb53122d16ea7a19..b2dcc445aca1006614a1d036a2f0eab1dfd07685 100644 (file)
@@ -28,7 +28,7 @@
 
 int main(int argc, char **argv) {
   testing::InitGoogleTest(&argc, argv);
-  google::ParseCommandLineFlags(&argc, &argv, true);
+  gflags::ParseCommandLineFlags(&argc, &argv, true);
   google::InitGoogleLogging(argv[0]);
 
   return RUN_ALL_TESTS();