diff --git a/extern/libmv/CMakeLists.txt b/extern/libmv/CMakeLists.txt index 6c716b5752c..f7173c3b1e1 100644 --- a/extern/libmv/CMakeLists.txt +++ b/extern/libmv/CMakeLists.txt @@ -44,6 +44,8 @@ if(WITH_LIBMV) ) list(APPEND INC + third_party/gflags + third_party/glog/src third_party/ceres/include ../../intern/guardedalloc ) @@ -218,10 +220,6 @@ if(WITH_LIBMV) third_party/glog/src/symbolize.h third_party/glog/src/utilities.h ) - - list(APPEND INC - third_party/glog/src - ) endif() else() list(APPEND SRC diff --git a/extern/libmv/ChangeLog b/extern/libmv/ChangeLog index 641d2518fb8..c9df808e1b4 100644 --- a/extern/libmv/ChangeLog +++ b/extern/libmv/ChangeLog @@ -1,3 +1,135 @@ +commit a4f387680dbc1f8818fe3cd79174a9983127d89e +Author: Sergey Sharybin +Date: Thu Mar 20 23:07:34 2014 +0600 + + Compilation fixes for MinGW + + Many thanks to Antony Riakiotakis for the patch! + +commit f1aefcbf58fe04ea2967434f39f703bb486777c8 +Author: Sergey Sharybin +Date: Thu Feb 27 16:21:19 2014 +0600 + + Implement separate BA step for tracks which have constant zero weight + + This is needed to minimize their reprojection error over the footage. + Without this extra step positions of such tracks were calculated by + algebraic intersection code only, which doesn't give best precision. + +commit bcf7f9470b2ea33cf89a31a72037ec03be631637 +Author: Sergey Sharybin +Date: Thu Feb 27 14:16:42 2014 +0600 + + Avoid zero-sized problem when doing euclidean intersection + + Zero-sized problem might occur when intersecting track with + constant zero weight. For such tracks we'll just use result + of algebraic intersection. + + TODO: We probably need to have a separate BA step to adjust + positions of tracks with constant zero weight. + +commit f884bb20a93189b8210639f3de939c64177d66b3 +Author: Sergey Sharybin +Date: Wed Feb 26 18:00:40 2014 +0600 + + Ignore zero weighted markers in keyframe selection + + It doesn't make sense to use zero-weighted tracks as a correspondences + in keyframe selection. + + Such tracks are not guaranteed to be tracked accurately because their + purpose is to add reference points in 3D space without affecting the + solution. + +commit 74db5175cdbcabe673b82eef59c88fb7f342c43f +Author: Sergey Sharybin +Date: Wed Feb 26 13:23:02 2014 +0600 + + Tweaks to make bundling into Blender warning-less + + Mainly issue i caused by conflicts in include directories, + so glog used to include config.h from gflags. It might be + fixed by splitting gflags/glog from Libmv in Blender build + system but that's not something fun to work on. Fixed by + making include directories bit more explicit. + + Also solved no-previous-prototype warnings. + +commit bc4bc66af0115069562b79e837ccf4fd95c8f97e +Author: Sergey Sharybin +Date: Fri Feb 21 14:55:13 2014 +0600 + + Raise epsilon used for model solver test + + It was too much small leading to false failure triggering + caused simply by precision issues. + +commit bf750590a6af4af3622c01fd1004c44da60484a7 +Author: Sergey Sharybin +Date: Tue Feb 18 23:35:52 2014 +0600 + + Made it possible to link against Ceres installed on the system + + Main purpose of this is to get away from bundled Ceres library + which is not so trivial to re-bundle and takes some to do this + (not talking about CMake options conflicts and pollution). + + Enabled by setting WITH_SYSTEM_CERES=ON. Default paths to search + Ceres library: + + - /usr/local + - /sw + - /opt/local + - /opt/csw + - /opt/lib/ceres + + You might also specify Ceres root directory using CERES_ROOT_DIR + variable (both CMake and environment variables are supported). + + If your Ceres is build statically, you're to control all additional + libraries needed to link against using CMAKE_EXE_LINKER_FLAGS. + +commit c9156fbf80c86853806844b754b1e48f45c5ec11 +Author: Sergey Sharybin +Date: Tue Feb 18 19:38:22 2014 +0600 + + Remove .orig file which was added by accident + +commit 62597e3cf0f266a2fefec415c89759e502793e06 +Author: Sergey Sharybin +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 +Date: Tue Feb 18 18:46:08 2014 +0600 + + Tweak Ceres CMake to detect uninstall target properly on Windows + +commit 98a281d58ce2301f3dd239a97a448e53f48d0258 +Author: Sergey Sharybin +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 +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. + commit b1381540305d69c702eb2f051bd543fb5c1c3e2c Author: Sergey Sharybin Date: Thu Feb 6 18:01:58 2014 +0600 @@ -538,156 +670,3 @@ Author: Sergey Sharybin Date: Fri May 10 13:27:21 2013 +0600 Left extra debugging print in reconstruction scale by accident. - -commit 7971967d24e3d8d505bd6e54523161ab5dd5b728 -Author: Sergey Sharybin -Date: Fri May 10 12:23:03 2013 +0600 - - Add check for points behind camera in euclidan BA cost functor - - In cases keyframes are no so good, algebraic two frames construction - could produce result, for which more aggressive Ceres-based BA code - will fall to a solution for which points goes behind the camera, - which is not so nice. - - Seems in newer Ceres returning false from cost functor wouldn't - abort solution, but will restrict solver from moving points behind - the camera. - - Works fine in own tests, but requires more tests. - -commit f34e73f6bd0041a31f779a78e1c2324f9799a4a2 -Author: Sergey Sharybin -Date: Wed Apr 24 22:06:38 2013 +0600 - - Forgot to add reconstruction scale to CMakeLists - -commit de08cbaebe1b95673c4bc8f639aa0228414cf4a2 -Author: Sergey Sharybin -Date: Wed Apr 24 19:40:39 2013 +0600 - - Reconstructed scene scale ambiguity improvement - - Added a function EuclideanScaleToUnity() which is - aimed to solve scale ambiguity by scaling solution - in a way cameras centers variance in unity. - - Currently only available for euclidean pipeline, - projective one is not finished anyway. - -commit 30ecb7dd075527c0e49220744bae65ec208dbdf5 -Author: Sergey Sharybin -Date: Tue Apr 23 01:41:29 2013 +0600 - - Use epsilon in modal solver test - - Default epsilon for isApprox was too small, - leading to some false test failures. - -commit d03b303c171b0b0a33ed0b31c9a744c9676492a9 -Author: Sergey Sharybin -Date: Tue Apr 23 01:35:56 2013 +0600 - - Update Ceres to current HEAD - - Brings optimization for DENSE_NORMAL_CHOLESKY and - also fixes threading issues with BLAS. - -commit 0a352686de0e87d59a2e37dbd0fddb351cbea2b7 -Author: Sergey Sharybin -Date: Mon Apr 15 05:35:33 2013 +0600 - - Fix for bundle adjusting with motion restricted - - Was a bug introduced in previous commit, which - was trying to set parameterization for non-existing - camera->t parameter block. - - Replaced with subset parameterization. - - Also added basic synthetic unit test for modal solver. - -commit 1742515b89ad5da53be95bfc574cbeffc51dc0e2 -Author: Sergey Sharybin -Date: Mon Apr 8 23:33:20 2013 +0600 - - Bundle adjustment improvements - - - Get rid of rotation matrix parameterization, - use angle-axis instead. - - Also Joined rotation and translation into - a single parameter block. - - This made minimization go significantly faster, - like 1.3x times in average. - - - Fix first camera when bundling. This is to - address orientation ambiguity. - - Reconstruction result could still vary in - size, but that's another issue to be addressed - later. - - Additional change: - - Split EuclideanBundleCommonIntrinsics into - smaller functions, so it's now a bit easier - to follow. - -commit 74bbeabf1c4570bfe04f3034afcde95134b3e161 -Author: Sergey Sharybin -Date: Mon Apr 8 23:31:57 2013 +0600 - - Update Ceres to current HEAD - - Brings up some noticeable speed improvements. In particular - the automatic differentiation and bundle adjustment solvers. - -commit e47519b0442527533ee046dd9881212d169561da -Author: Sergey Sharybin -Date: Mon Apr 8 02:21:26 2013 +0600 - - Corrected path to gflags - - Currently tools/track.cc is not used, but let's - keep things a bit more up-to-date :) - -commit f617741b1f2a0ac7981dd71144eba187521d9ac4 -Author: Sergey Sharybin -Date: Mon Apr 8 02:17:16 2013 +0600 - - Re-enable tests for multiview and image - - For as long code is in repo and used by some tools - better to have it covered by tests. - - Some of them are failing tho, but that's completely - different story to be addressed later. - -commit 7dbb5a37333fb6c5a729b8bafb317ea210735cbc -Author: Sergey Sharybin -Date: Mon Apr 8 02:10:07 2013 +0600 - - Do not modify cache's CMAKE_CXX_FLAGS_RELEASE when configuring Ceres - - Otherwise you'll have infinite appending of Ceres-specific flags - on every saving of any CmakeLists.txt. - -commit b413d22280de2481a2e2acdcda8431f601d65448 -Author: Sergey Sharybin -Date: Sun Apr 7 21:53:23 2013 +0600 - - Fixed compilation with BUILD_TOOLS enabled - - This commit mainly reverts parts of following commits: - 0eebc21db831211738acc938566bbc29d68d45db - d8109b7a4fede1660e0dbd73735f1a9e3fd79eec - e59595806c045916ab4ef15ef7047c1a728b2da9 - 2d6cd58ee1cd7c5073980f358c71b2898ad16b4c - - They declared lots of stuff deprecated, but in - fact it's not deprecated just a bit different - usage pipeline. Anyway, deprecation shall not - happen spontaneously as a part of other changes. - And for sure shall not break anything. diff --git a/extern/libmv/SConscript b/extern/libmv/SConscript index 544e5fda381..796819faa55 100644 --- a/extern/libmv/SConscript +++ b/extern/libmv/SConscript @@ -26,7 +26,7 @@ if env['WITH_BF_LIBMV']: src += env.Glob('libmv/tracking/*.cc') src += env.Glob('third_party/gflags/*.cc') - incs += ' ../Eigen3 third_party/ceres/include ../../intern/guardedalloc' + incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include ../../intern/guardedalloc' incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/extern/libmv/bundle.sh b/extern/libmv/bundle.sh index 48d68435ef7..c98f8a31045 100755 --- a/extern/libmv/bundle.sh +++ b/extern/libmv/bundle.sh @@ -132,6 +132,8 @@ if(WITH_LIBMV) ) list(APPEND INC + third_party/gflags + third_party/glog/src third_party/ceres/include ../../intern/guardedalloc ) @@ -195,10 +197,6 @@ ${third_glog_sources} ${third_glog_headers} ) - - list(APPEND INC - third_party/glog/src - ) endif() else() list(APPEND SRC @@ -237,7 +235,7 @@ if env['WITH_BF_LIBMV']: src = env.Glob("libmv-capi.cc") $src - incs += ' ../Eigen3 third_party/ceres/include ../../intern/guardedalloc' + incs += ' ../Eigen3 third_party/gflags third_party/glog/src third_party/ceres/include ../../intern/guardedalloc' incs += ' ' + env['BF_PNG_INC'] incs += ' ' + env['BF_ZLIB_INC'] diff --git a/extern/libmv/third_party/gflags/gflags/gflags_declare.h b/extern/libmv/third_party/gflags/gflags/gflags_declare.h index e3013826d53..503b686657f 100644 --- a/extern/libmv/third_party/gflags/gflags/gflags_declare.h +++ b/extern/libmv/third_party/gflags/gflags/gflags_declare.h @@ -49,17 +49,17 @@ #endif namespace google { -#if 1 // the C99 format +#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 1 // the BSD format +#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 0 // the windows (vc7) format +#elif defined(_MSC_VER) // the windows (vc7) format typedef __int32 int32; typedef unsigned __int32 uint32; typedef __int64 int64; diff --git a/extern/libmv/third_party/glog/ChangeLog b/extern/libmv/third_party/glog/ChangeLog index 6ac0b0f0575..d1b42484416 100644 --- a/extern/libmv/third_party/glog/ChangeLog +++ b/extern/libmv/third_party/glog/ChangeLog @@ -1,3 +1,18 @@ +2013-02-01 Google Inc. + + * google-glog: version 0.3.3 + * Add --disable-rtti option for configure. + * Visual Studio build and test fix. + * QNX build fix (thanks vanuan). + * Reduce warnings. + * Fixed LOG_SYSRESULT (thanks ukai). + * FreeBSD build fix (thanks yyanagisawa). + * Clang build fix. + * Now users can re-initialize glog after ShutdownGoogleLogging. + * Color output support by GLOG_colorlogtostderr (thanks alexs). + * Now glog's ABI around flags are compatible with gflags. + * Document mentions how to modify flags from user programs. + 2012-01-12 Google Inc. * google-glog: version 0.3.2 diff --git a/extern/libmv/third_party/glog/README.libmv b/extern/libmv/third_party/glog/README.libmv index 345bc9f5969..eb4b2ea3379 100644 --- a/extern/libmv/third_party/glog/README.libmv +++ b/extern/libmv/third_party/glog/README.libmv @@ -1,25 +1,9 @@ Project: Google Logging URL: http://code.google.com/p/google-glog/ License: New BSD -Upstream version: 0.3.2 +Upstream version: 0.3.3, r139 Local modifications: - -Upgrading Notes -* Replace with "third_party/gflags/gflags/gflags.h" which is easier - to setup things in libmv and also helps with setting up building libmv into - external applications. -* Replace "glog/logging.h" and "glog/logging.h" with and - which is needed on Windows platform because otherwise files like logging.cc will be using - relative path which points to headers used by linux instead of headers need to be used - on Windows. -* Replace _asm int 3 with __debugbreak(). Such assembler code is obsolete and doesn't work - with 64bit versions of MSVC compilers. -* Do not use stacktrace for MinGW and FreeBSD because it leads into issues accessing - some specific data on this platforms. -* Define HAVE_LIB_GFLAGS for Windows builds. -* Do not define __declspec(dllimport) for MinGW platforms. -* Setup proper includes and datatypes for int32, uint32, int64 and uint64 for MinGW -* Do not define va_copy for MinGW platforms (it's already defined there). -* Patch localtime_r to be working fine with MinGW, disable strerror_r for MinGW because - of lack of needed functions. -* Added -fPIC flag, so shared libraries from Ceres could be linked against static glog +* Added per-platform config.h files so no configuration-time + checks for functions and so are needed. +* See glog_tweaks.patch to see other tweaks which are done + against glog upstream. diff --git a/extern/libmv/third_party/glog/src/base/commandlineflags.h b/extern/libmv/third_party/glog/src/base/commandlineflags.h index 483a96ee80b..529540ea461 100644 --- a/extern/libmv/third_party/glog/src/base/commandlineflags.h +++ b/extern/libmv/third_party/glog/src/base/commandlineflags.h @@ -48,56 +48,57 @@ #ifndef BASE_COMMANDLINEFLAGS_H__ #define BASE_COMMANDLINEFLAGS_H__ -#include "config.h" +#include "../config.h" #include #include // for memchr #include // for getenv #ifdef HAVE_LIB_GFLAGS -#include "third_party/gflags/gflags/gflags.h" +#include #else -#include +#include "glog/logging.h" -#define DECLARE_VARIABLE(type, name, tn) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name -#define DEFINE_VARIABLE(type, name, value, meaning, tn) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ - char FLAGS_no##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name +#define DECLARE_VARIABLE(type, shorttype, name, tn) \ + namespace fL##shorttype { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using fL##shorttype::FLAGS_##name +#define DEFINE_VARIABLE(type, shorttype, name, value, meaning, tn) \ + namespace fL##shorttype { \ + GOOGLE_GLOG_DLL_DECL type FLAGS_##name(value); \ + char FLAGS_no##name; \ + } \ + using fL##shorttype::FLAGS_##name // bool specialization #define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, name, bool) + DECLARE_VARIABLE(bool, B, name, bool) #define DEFINE_bool(name, value, meaning) \ - DEFINE_VARIABLE(bool, name, value, meaning, bool) + DEFINE_VARIABLE(bool, B, name, value, meaning, bool) // int32 specialization #define DECLARE_int32(name) \ - DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, name, int32) + DECLARE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, int32) #define DEFINE_int32(name, value, meaning) \ - DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, name, value, meaning, int32) + DEFINE_VARIABLE(GOOGLE_NAMESPACE::int32, I, name, value, meaning, int32) // Special case for string, because we have to specify the namespace // std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name -#define DEFINE_string(name, value, meaning) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name(value); \ - char FLAGS_no##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#define DECLARE_string(name) \ + namespace fLS { \ + extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ + } \ + using fLS::FLAGS_##name +#define DEFINE_string(name, value, meaning) \ + namespace fLS { \ + std::string FLAGS_##name##_buf(value); \ + GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name = FLAGS_##name##_buf; \ + char FLAGS_no##name; \ + } \ + using fLS::FLAGS_##name #endif // HAVE_LIB_GFLAGS diff --git a/extern/libmv/third_party/glog/src/base/mutex.h b/extern/libmv/third_party/glog/src/base/mutex.h index 7ba88cb5a63..36fc55c4dcb 100644 --- a/extern/libmv/third_party/glog/src/base/mutex.h +++ b/extern/libmv/third_party/glog/src/base/mutex.h @@ -102,12 +102,14 @@ #ifndef GOOGLE_MUTEX_H_ #define GOOGLE_MUTEX_H_ -#include "config.h" // to figure out pthreads support +#include "../config.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__) -# define WIN32_LEAN_AND_MEAN // We only need minimal includes +# ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN // We only need minimal includes +# endif # ifdef GMUTEX_TRYLOCK // We need Windows NT or later for TryEnterCriticalSection(). If you // don't need that functionality, you can remove these _WIN32_WINNT @@ -117,9 +119,13 @@ # endif # endif // To avoid macro definition of ERROR. -# define NOGDI +# ifndef NOGDI +# define NOGDI +# endif // To avoid macro definition of min/max. -# define NOMINMAX +# ifndef NOMINMAX +# define NOMINMAX +# endif # include typedef CRITICAL_SECTION MutexType; #elif defined(HAVE_PTHREAD) && defined(HAVE_RWLOCK) diff --git a/extern/libmv/third_party/glog/src/config_freebsd.h b/extern/libmv/third_party/glog/src/config_freebsd.h index a671a0080b3..a1fe76fe806 100644 --- a/extern/libmv/third_party/glog/src/config_freebsd.h +++ b/extern/libmv/third_party/glog/src/config_freebsd.h @@ -46,12 +46,18 @@ /* define if the compiler implements namespaces */ #define HAVE_NAMESPACES 1 +/* Define if you have the 'pread' function */ +#define HAVE_PREAD 1 + /* Define if you have POSIX threads libraries and header files. */ #define HAVE_PTHREAD 1 /* Define to 1 if you have the header file. */ #define HAVE_PWD_H 1 +/* Define if you have the 'pwrite' function */ +#define HAVE_PWRITE 1 + /* define if the compiler implements pthread_rwlock_* */ #define HAVE_RWLOCK 1 diff --git a/extern/libmv/third_party/glog/src/config_hurd.h b/extern/libmv/third_party/glog/src/config_hurd.h index 47aefa423d6..81e8ed7bac3 100644 --- a/extern/libmv/third_party/glog/src/config_hurd.h +++ b/extern/libmv/third_party/glog/src/config_hurd.h @@ -46,12 +46,18 @@ /* define if the compiler implements namespaces */ #define HAVE_NAMESPACES 1 +/* Define if you have the 'pread' function */ +#define HAVE_PREAD 1 + /* Define if you have POSIX threads libraries and header files. */ #define HAVE_PTHREAD 1 /* Define to 1 if you have the header file. */ #define HAVE_PWD_H 1 +/* Define if you have the 'pwrite' function */ +#define HAVE_PWRITE 1 + /* define if the compiler implements pthread_rwlock_* */ #define HAVE_RWLOCK 1 diff --git a/extern/libmv/third_party/glog/src/config_linux.h b/extern/libmv/third_party/glog/src/config_linux.h index 5877029882a..7741ddebb63 100644 --- a/extern/libmv/third_party/glog/src/config_linux.h +++ b/extern/libmv/third_party/glog/src/config_linux.h @@ -46,12 +46,18 @@ /* define if the compiler implements namespaces */ #define HAVE_NAMESPACES 1 +/* Define if you have the 'pread' function */ +#define HAVE_PREAD 1 + /* Define if you have POSIX threads libraries and header files. */ #define HAVE_PTHREAD 1 /* Define to 1 if you have the header file. */ #define HAVE_PWD_H 1 +/* Define if you have the 'pwrite' function */ +#define HAVE_PWRITE 1 + /* define if the compiler implements pthread_rwlock_* */ #define HAVE_RWLOCK 1 diff --git a/extern/libmv/third_party/glog/src/config_mac.h b/extern/libmv/third_party/glog/src/config_mac.h index 9756fde22f3..1695472f031 100644 --- a/extern/libmv/third_party/glog/src/config_mac.h +++ b/extern/libmv/third_party/glog/src/config_mac.h @@ -46,12 +46,18 @@ /* define if the compiler implements namespaces */ #define HAVE_NAMESPACES 1 +/* Define if you have the 'pread' function */ +#define HAVE_PREAD 1 + /* Define if you have POSIX threads libraries and header files. */ #define HAVE_PTHREAD 1 /* Define to 1 if you have the header file. */ #define HAVE_PWD_H 1 +/* Define if you have the 'pwrite' function */ +#define HAVE_PWRITE 1 + /* define if the compiler implements pthread_rwlock_* */ #define HAVE_RWLOCK 1 diff --git a/extern/libmv/third_party/glog/src/glog/logging.h b/extern/libmv/third_party/glog/src/glog/logging.h index 005649c17c2..247c0467b6a 100644 --- a/extern/libmv/third_party/glog/src/glog/logging.h +++ b/extern/libmv/third_party/glog/src/glog/logging.h @@ -33,24 +33,23 @@ // Pretty much everybody needs to #include this file so that they can // log various happenings. // +#ifdef WIN32 +# include "windows/glog/logging.h" +#else // WIN32 + #ifndef _LOGGING_H_ #define _LOGGING_H_ #include #include #include +#include +#include +#include #include #if 1 # include #endif -#ifdef __DEPRECATED -// Make GCC quiet. -# undef __DEPRECATED -# include -# define __DEPRECATED -#else -# include -#endif #include // Annoying stuff for windows -- makes sure clients can import these functions @@ -61,6 +60,14 @@ # define GOOGLE_GLOG_DLL_DECL # endif #endif +#if defined(_MSC_VER) +#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ + __pragma(warning(disable:n)) +#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop)) +#else +#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) +#define GLOG_MSVC_POP_WARNING() +#endif // We care a lot about number of bits things take up. Unfortunately, // systems define their bit-specific ints in a lot of different ways. @@ -79,7 +86,7 @@ #endif #if 1 -#include "third_party/gflags/gflags/gflags.h" +#include #endif namespace google { @@ -126,8 +133,12 @@ typedef unsigned __int64 uint64; #ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN #if 1 #define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) +#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) #else #define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x +#define GOOGLE_PREDICT_FALSE(x) x +#define GOOGLE_PREDICT_TRUE(x) x #endif #endif @@ -286,27 +297,27 @@ typedef unsigned __int64 uint64; #ifndef DECLARE_VARIABLE #define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, name, tn) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name +#define DECLARE_VARIABLE(type, shorttype, name, tn) \ + namespace fL##shorttype { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using fL##shorttype::FLAGS_##name // bool specialization #define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, name, bool) + DECLARE_VARIABLE(bool, B, name, bool) // int32 specialization #define DECLARE_int32(name) \ - DECLARE_VARIABLE(google::int32, name, int32) + DECLARE_VARIABLE(google::int32, I, name, int32) // Special case for string, because we have to specify the namespace // std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#define DECLARE_string(name) \ + namespace fLS { \ + extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ + } \ + using fLS::FLAGS_##name #endif // Set whether log messages go to stderr instead of logfiles @@ -315,6 +326,9 @@ DECLARE_bool(logtostderr); // Set whether log messages go to stderr in addition to logfiles. DECLARE_bool(alsologtostderr); +// Set color messages logged to stderr (if supported by terminal). +DECLARE_bool(colorlogtostderr); + // Log messages at a level >= this flag are automatically sent to // stderr in addition to log files. DECLARE_int32(stderrthreshold); @@ -447,15 +461,16 @@ DECLARE_bool(stop_logging_if_full_disk); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) // A very useful logging macro to log windows errors: #define LOG_SYSRESULT(result) \ - if (FAILED(result)) { \ - LPTSTR message = NULL; \ - LPTSTR msg = reinterpret_cast(&message); \ - DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ + if (FAILED(HRESULT_FROM_WIN32(result))) { \ + LPSTR message = NULL; \ + LPSTR msg = reinterpret_cast(&message); \ + DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ FORMAT_MESSAGE_FROM_SYSTEM, \ 0, result, 0, msg, 100, NULL); \ if (message_length > 0) { \ google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \ - &google::LogMessage::SendToLog).stream() << message; \ + &google::LogMessage::SendToLog).stream() \ + << reinterpret_cast(message); \ LocalFree(message); \ } \ } @@ -597,18 +612,68 @@ inline std::ostream& operator<<( namespace google { -// Build the error message string. -template -std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { - // It means that we cannot use stl_logging if compiler doesn't - // support using expression for operator. - // TODO(hamaji): Figure out a way to fix. -#if 1 - using ::operator<<; -#endif - std::strstream ss; - ss << names << " (" << v1 << " vs. " << v2 << ")"; - return new std::string(ss.str(), ss.pcount()); +// This formats a value for a failing CHECK_XX statement. Ordinarily, +// it uses the definition for operator<<, with a few special cases below. +template +inline void MakeCheckOpValueString(std::ostream* os, const T& v) { + (*os) << v; +} + +// Overrides for char types provide readable values for unprintable +// characters. +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const char& v); +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const signed char& v); +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); + +// Build the error message string. Specify no inlining for code size. +template +std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) + __attribute__ ((noinline)); + +namespace base { +namespace internal { + +// If "s" is less than base_logging::INFO, returns base_logging::INFO. +// If "s" is greater than base_logging::FATAL, returns +// base_logging::ERROR. Otherwise, returns "s". +LogSeverity NormalizeSeverity(LogSeverity s); + +} // namespace internal + +// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX +// statement. See MakeCheckOpString for sample usage. Other +// approaches were considered: use of a template method (e.g., +// base::BuildCheckOpString(exprtext, base::Print, &v1, +// base::Print, &v2), however this approach has complications +// related to volatile arguments and function-pointer arguments). +class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { + public: + // Inserts "exprtext" and " (" to the stream. + explicit CheckOpMessageBuilder(const char *exprtext); + // Deletes "stream_". + ~CheckOpMessageBuilder(); + // For inserting the first variable. + std::ostream* ForVar1() { return stream_; } + // For inserting the second variable (adds an intermediate " vs. "). + std::ostream* ForVar2(); + // Get the result (inserts the closing ")"). + std::string* NewString(); + + private: + std::ostringstream *stream_; +}; + +} // namespace base + +template +std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { + base::CheckOpMessageBuilder comb(exprtext); + MakeCheckOpValueString(comb.ForVar1(), v1); + MakeCheckOpValueString(comb.ForVar2(), v2); + return comb.NewString(); } // Helper functions for CHECK_OP macro. @@ -616,26 +681,26 @@ std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { // will not instantiate the template version of the function on values of // unnamed enum type - see comment below. #define DEFINE_CHECK_OP_IMPL(name, op) \ - template \ - inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ - const char* names) { \ - if (v1 op v2) return NULL; \ - else return MakeCheckOpString(v1, v2, names); \ + template \ + inline std::string* name##Impl(const T1& v1, const T2& v2, \ + const char* exprtext) { \ + if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ + else return MakeCheckOpString(v1, v2, exprtext); \ } \ - inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ - return Check##name##Impl(v1, v2, names); \ + inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ + return name##Impl(v1, v2, exprtext); \ } -// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h -// provides its own #defines for the simpler names EQ, NE, LE, etc. +// We use the full name Check_EQ, Check_NE, etc. in case the file including +// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. // This happens if, for example, those are used as token names in a // yacc grammar. -DEFINE_CHECK_OP_IMPL(_EQ, ==) -DEFINE_CHECK_OP_IMPL(_NE, !=) -DEFINE_CHECK_OP_IMPL(_LE, <=) -DEFINE_CHECK_OP_IMPL(_LT, < ) -DEFINE_CHECK_OP_IMPL(_GE, >=) -DEFINE_CHECK_OP_IMPL(_GT, > ) +DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? +DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. +DEFINE_CHECK_OP_IMPL(Check_LE, <=) +DEFINE_CHECK_OP_IMPL(Check_LT, < ) +DEFINE_CHECK_OP_IMPL(Check_GE, >=) +DEFINE_CHECK_OP_IMPL(Check_GT, > ) #undef DEFINE_CHECK_OP_IMPL // Helper macro for binary operators. @@ -940,52 +1005,65 @@ const LogSeverity GLOG_0 = GLOG_ERROR; #define DLOG_ASSERT(condition) \ true ? (void) 0 : LOG_ASSERT(condition) +// MSVC warning C4127: conditional expression is constant #define DCHECK(condition) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK(condition) + GLOG_MSVC_POP_WARNING() CHECK(condition) #define DCHECK_EQ(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_EQ(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2) #define DCHECK_NE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_NE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2) #define DCHECK_LE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_LE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2) #define DCHECK_LT(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_LT(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2) #define DCHECK_GE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_GE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2) #define DCHECK_GT(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_GT(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2) +// You may see warnings in release mode if you don't use the return +// value of DCHECK_NOTNULL. Please just use DCHECK for such cases. #define DCHECK_NOTNULL(val) (val) #define DCHECK_STREQ(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STREQ(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2) #define DCHECK_STRCASEEQ(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRCASEEQ(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2) #define DCHECK_STRNE(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRNE(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2) #define DCHECK_STRCASENE(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRCASENE(str1, str2) - + GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2) #endif // NDEBUG @@ -1002,6 +1080,29 @@ const LogSeverity GLOG_0 = GLOG_ERROR; #define VLOG_IF_EVERY_N(verboselevel, condition, n) \ LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) +namespace base_logging { + +// LogMessage::LogStream is a std::ostream backed by this streambuf. +// This class ignores overflow and leaves two bytes at the end of the +// buffer to allow for a '\n' and '\0'. +class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf { + public: + // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'. + LogStreamBuf(char *buf, int len) { + setp(buf, buf + len - 2); + } + // This effectively ignores overflow. + virtual int_type overflow(int_type ch) { + return ch; + } + + // Legacy public ostrstream method. + size_t pcount() const { return pptr() - pbase(); } + char* pbase() const { return std::streambuf::pbase(); } +}; + +} // namespace base_logging + // // This class more or less represents a particular log message. You // create an instance of LogMessage and then stream stuff to it. @@ -1031,22 +1132,30 @@ public: #ifdef _MSC_VER # pragma warning(disable: 4275) #endif - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { #ifdef _MSC_VER # pragma warning(default: 4275) #endif public: - LogStream(char *buf, int len, int ctr_in) - : ostrstream(buf, len), - ctr_(ctr_in) { - self_ = this; + LogStream(char *buf, int len, int ctr) + : std::ostream(NULL), + streambuf_(buf, len), + ctr_(ctr), + self_(this) { + rdbuf(&streambuf_); } int ctr() const { return ctr_; } - void set_ctr(int ctr_in) { ctr_ = ctr_in; } + void set_ctr(int ctr) { ctr_ = ctr; } LogStream* self() const { return self_; } + // Legacy std::streambuf methods. + size_t pcount() const { return streambuf_.pcount(); } + char* pbase() const { return streambuf_.pbase(); } + char* str() const { return pbase(); } + private: + base_logging::LogStreamBuf streambuf_; int ctr_; // Counter hack (for the LOG_EVERY_X() macro) LogStream *self_; // Consistency check hack }; @@ -1115,13 +1224,15 @@ public: // Call abort() or similar to perform LOG(FATAL) crash. static void Fail() __attribute__ ((noreturn)); - std::ostream& stream() { return *(data_->stream_); } + std::ostream& stream(); - int preserved_errno() const { return data_->preserved_errno_; } + int preserved_errno() const; // Must be called without the log_mutex held. (L < log_mutex) static int64 num_messages(int severity); + struct LogMessageData; + private: // Fully internal SendMethod cases: void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs @@ -1143,41 +1254,6 @@ private: // We keep the data in a separate struct so that each instance of // LogMessage uses less stack space. - struct GOOGLE_GLOG_DLL_DECL LogMessageData { - LogMessageData() {}; - - int preserved_errno_; // preserved errno - char* buf_; - char* message_text_; // Complete message text (points to selected buffer) - LogStream* stream_alloc_; - LogStream* stream_; - char severity_; // What level is this LogMessage logged at? - int line_; // line number where logging call is. - void (LogMessage::*send_method_)(); // Call this in destructor to send - union { // At most one of these is used: union to keep the size low. - LogSink* sink_; // NULL or sink to send message to - std::vector* outvec_; // NULL or vector to push message onto - std::string* message_; // NULL or string to write message into - }; - time_t timestamp_; // Time of creation of LogMessage - struct ::tm tm_time_; // Time of creation of LogMessage - size_t num_prefix_chars_; // # of chars of prefix in this message - size_t num_chars_to_log_; // # of chars of msg to send to log - size_t num_chars_to_syslog_; // # of chars of msg to send to syslog - const char* basename_; // basename of file that called LOG - const char* fullname_; // fullname of file that called LOG - bool has_been_flushed_; // false => data has not been flushed - bool first_fatal_; // true => this was first fatal msg - - ~LogMessageData(); - private: - LogMessageData(const LogMessageData&); - void operator=(const LogMessageData&); - }; - - static LogMessageData fatal_msg_data_exclusive_; - static LogMessageData fatal_msg_data_shared_; - LogMessageData* allocated_; LogMessageData* data_; @@ -1456,8 +1532,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); // be set to an empty string, if this function failed. This means, in most // cases, you do not need to check the error code and you can directly // use the value of "buf". It will never have an undefined value. +// DEPRECATED: Use StrError(int) instead. GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); +// A thread-safe replacement for strerror(). Returns a string describing the +// given POSIX error code. +GOOGLE_GLOG_DLL_DECL std::string StrError(int err); // A class for which we define operator<<, which does nothing. class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { @@ -1525,3 +1605,5 @@ GOOGLE_GLOG_DLL_DECL void InstallFailureWriter( } #endif // _LOGGING_H_ + +#endif // WIN32 diff --git a/extern/libmv/third_party/glog/src/glog/raw_logging.h b/extern/libmv/third_party/glog/src/glog/raw_logging.h index 65278f62803..b030f7f736d 100644 --- a/extern/libmv/third_party/glog/src/glog/raw_logging.h +++ b/extern/libmv/third_party/glog/src/glog/raw_logging.h @@ -33,6 +33,10 @@ // acquire any locks, and can therefore be used by low-level memory // allocation and synchronization code. +#ifdef WIN32 +# include "windows/glog/raw_logging.h" +#else // WIN32 + #ifndef BASE_RAW_LOGGING_H_ #define BASE_RAW_LOGGING_H_ @@ -183,3 +187,5 @@ GOOGLE_GLOG_DLL_DECL void RawLog__SetLastTime(const struct tm& t, int usecs); } #endif // BASE_RAW_LOGGING_H_ + +#endif // WIN32 diff --git a/extern/libmv/third_party/glog/src/logging.cc b/extern/libmv/third_party/glog/src/logging.cc index 57d5e24122c..03c427d8dc1 100644 --- a/extern/libmv/third_party/glog/src/logging.cc +++ b/extern/libmv/third_party/glog/src/logging.cc @@ -34,7 +34,6 @@ #include #include #include -#include #ifdef HAVE_UNISTD_H # include // For _exit. #endif @@ -59,8 +58,8 @@ #include // for errno #include #include "base/commandlineflags.h" // to get the program name -#include -#include +#include "glog/logging.h" +#include "glog/raw_logging.h" #include "base/googleinit.h" #ifdef HAVE_STACKTRACE @@ -69,7 +68,6 @@ using std::string; using std::vector; -using std::ostrstream; using std::setw; using std::setfill; using std::hex; @@ -77,7 +75,17 @@ using std::dec; using std::min; using std::ostream; using std::ostringstream; -using std::strstream; + +using std::FILE; +using std::fwrite; +using std::fclose; +using std::fflush; +using std::fprintf; +using std::perror; + +#ifdef __QNX__ +using std::fdopen; +#endif // There is no thread annotation support. #define EXCLUSIVE_LOCKS_REQUIRED(mu) @@ -94,6 +102,8 @@ GLOG_DEFINE_bool(logtostderr, BoolFromEnv("GOOGLE_LOGTOSTDERR", false), "log messages go to stderr instead of logfiles"); GLOG_DEFINE_bool(alsologtostderr, BoolFromEnv("GOOGLE_ALSOLOGTOSTDERR", false), "log messages go to stderr in addition to logfiles"); +GLOG_DEFINE_bool(colorlogtostderr, false, + "color messages logged to stderr (if supported by terminal)"); #ifdef OS_LINUX GLOG_DEFINE_bool(drop_log_memory, true, "Drop in-memory buffers of log contents. " "Logs can grow very quickly and they are rarely read before they " @@ -169,6 +179,38 @@ GLOG_DEFINE_string(log_backtrace_at, "", // TODO(hamaji): consider windows #define PATH_SEPARATOR '/' +#ifndef HAVE_PREAD +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) + return -1; + if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) + return -1; + ssize_t len = read(fd, buf, count); + if (len < 0) + return len; + if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return len; +} +#endif // !HAVE_PREAD + +#ifndef HAVE_PWRITE +static ssize_t pwrite(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) + return -1; + if (lseek(fd, offset, SEEK_CUR) == (off_t)-1) + return -1; + ssize_t len = write(fd, buf, count); + if (len < 0) + return len; + if (lseek(fd, orig_offset, SEEK_SET) == (off_t)-1) + return -1; + return len; +} +#endif // !HAVE_PWRITE + static void GetHostName(string* hostname) { #if defined(HAVE_SYS_UTSNAME_H) struct utsname buf; @@ -191,13 +233,125 @@ static void GetHostName(string* hostname) { #endif } +// Returns true iff terminal supports using colors in output. +static bool TerminalSupportsColor() { + bool term_supports_color = false; +#ifdef OS_WINDOWS + // on Windows TERM variable is usually not set, but the console does + // support colors. + term_supports_color = true; +#else + // On non-Windows platforms, we rely on the TERM variable. + const char* const term = getenv("TERM"); + if (term != NULL && term[0] != '\0') { + term_supports_color = + !strcmp(term, "xterm") || + !strcmp(term, "xterm-color") || + !strcmp(term, "xterm-256color") || + !strcmp(term, "screen") || + !strcmp(term, "linux") || + !strcmp(term, "cygwin"); + } +#endif + return term_supports_color; +} + _START_GOOGLE_NAMESPACE_ +enum GLogColor { + COLOR_DEFAULT, + COLOR_RED, + COLOR_GREEN, + COLOR_YELLOW +}; + +static GLogColor SeverityToColor(LogSeverity severity) { + assert(severity >= 0 && severity < NUM_SEVERITIES); + GLogColor color = COLOR_DEFAULT; + switch (severity) { + case GLOG_INFO: + color = COLOR_DEFAULT; + break; + case GLOG_WARNING: + color = COLOR_YELLOW; + break; + case GLOG_ERROR: + case GLOG_FATAL: + color = COLOR_RED; + break; + default: + // should never get here. + assert(false); + } + return color; +} + +#ifdef OS_WINDOWS + +// Returns the character attribute for the given color. +WORD GetColorAttribute(GLogColor color) { + switch (color) { + case COLOR_RED: return FOREGROUND_RED; + case COLOR_GREEN: return FOREGROUND_GREEN; + case COLOR_YELLOW: return FOREGROUND_RED | FOREGROUND_GREEN; + default: return 0; + } +} + +#else + +// Returns the ANSI color code for the given color. +static const char* GetAnsiColorCode(GLogColor color) { + switch (color) { + case COLOR_RED: return "1"; + case COLOR_GREEN: return "2"; + case COLOR_YELLOW: return "3"; + case COLOR_DEFAULT: return ""; + }; + return NULL; // stop warning about return type. +} + +#endif // OS_WINDOWS + // Safely get max_log_size, overriding to 1 if it somehow gets defined as 0 static int32 MaxLogSize() { return (FLAGS_max_log_size > 0 ? FLAGS_max_log_size : 1); } +// An arbitrary limit on the length of a single log message. This +// is so that streaming can be done more efficiently. +const size_t LogMessage::kMaxLogMessageLen = 30000; + +struct LogMessage::LogMessageData { + LogMessageData(); + + int preserved_errno_; // preserved errno + // Buffer space; contains complete message text. + char message_text_[LogMessage::kMaxLogMessageLen+1]; + LogStream stream_; + char severity_; // What level is this LogMessage logged at? + int line_; // line number where logging call is. + void (LogMessage::*send_method_)(); // Call this in destructor to send + union { // At most one of these is used: union to keep the size low. + LogSink* sink_; // NULL or sink to send message to + std::vector* outvec_; // NULL or vector to push message onto + std::string* message_; // NULL or string to write message into + }; + time_t timestamp_; // Time of creation of LogMessage + struct ::tm tm_time_; // Time of creation of LogMessage + size_t num_prefix_chars_; // # of chars of prefix in this message + size_t num_chars_to_log_; // # of chars of msg to send to log + size_t num_chars_to_syslog_; // # of chars of msg to send to syslog + const char* basename_; // basename of file that called LOG + const char* fullname_; // fullname of file that called LOG + bool has_been_flushed_; // false => data has not been flushed + bool first_fatal_; // true => this was first fatal msg + + private: + LogMessageData(const LogMessageData&); + void operator=(const LogMessageData&); +}; + // A mutex that allows only one thread to log at a time, to keep things from // getting jumbled. Some other very uncommon logging operations (like // changing the destination file for log messages of a given severity) also @@ -279,7 +433,7 @@ class LogFileObject : public base::Logger { // Actually create a logfile using the value of base_filename_ and the // supplied argument time_pid_string // REQUIRES: lock_ is held - bool CreateLogfile(const char* time_pid_string); + bool CreateLogfile(const string& time_pid_string); }; } // namespace @@ -312,6 +466,9 @@ class LogDestination { static const int kNetworkBytes = 1400; static const string& hostname(); + static const bool& terminal_supports_color() { + return terminal_supports_color_; + } static void DeleteLogDestinations(); @@ -362,6 +519,7 @@ class LogDestination { static LogSeverity email_logging_severity_; static string addresses_; static string hostname_; + static bool terminal_supports_color_; // arbitrary global logging destinations. static vector* sinks_; @@ -383,6 +541,7 @@ string LogDestination::hostname_; vector* LogDestination::sinks_ = NULL; Mutex LogDestination::sink_mutex_; +bool LogDestination::terminal_supports_color_ = TerminalSupportsColor(); /* static */ const string& LogDestination::hostname() { @@ -503,6 +662,43 @@ inline void LogDestination::SetEmailLogging(LogSeverity min_severity, LogDestination::addresses_ = addresses; } +static void ColoredWriteToStderr(LogSeverity severity, + const char* message, size_t len) { + const GLogColor color = + (LogDestination::terminal_supports_color() && FLAGS_colorlogtostderr) ? + SeverityToColor(severity) : COLOR_DEFAULT; + + // Avoid using cerr from this module since we may get called during + // exit code, and cerr may be partially or fully destroyed by then. + if (COLOR_DEFAULT == color) { + fwrite(message, len, 1, stderr); + return; + } +#ifdef OS_WINDOWS + const HANDLE stderr_handle = GetStdHandle(STD_ERROR_HANDLE); + + // Gets the current text color. + CONSOLE_SCREEN_BUFFER_INFO buffer_info; + GetConsoleScreenBufferInfo(stderr_handle, &buffer_info); + const WORD old_color_attrs = buffer_info.wAttributes; + + // We need to flush the stream buffers into the console before each + // SetConsoleTextAttribute call lest it affect the text that is already + // printed but has not yet reached the console. + fflush(stderr); + SetConsoleTextAttribute(stderr_handle, + GetColorAttribute(color) | FOREGROUND_INTENSITY); + fwrite(message, len, 1, stderr); + fflush(stderr); + // Restores the text color. + SetConsoleTextAttribute(stderr_handle, old_color_attrs); +#else + fprintf(stderr, "\033[0;3%sm", GetAnsiColorCode(color)); + fwrite(message, len, 1, stderr); + fprintf(stderr, "\033[m"); // Resets the terminal to default. +#endif // OS_WINDOWS +} + static void WriteToStderr(const char* message, size_t len) { // Avoid using cerr from this module since we may get called during // exit code, and cerr may be partially or fully destroyed by then. @@ -512,7 +708,7 @@ static void WriteToStderr(const char* message, size_t len) { inline void LogDestination::MaybeLogToStderr(LogSeverity severity, const char* message, size_t len) { if ((severity >= FLAGS_stderrthreshold) || FLAGS_alsologtostderr) { - WriteToStderr(message, len); + ColoredWriteToStderr(severity, message, len); #ifdef OS_WINDOWS // On Windows, also output to the debugger ::OutputDebugStringA(string(message,len).c_str()); @@ -561,12 +757,12 @@ inline void LogDestination::LogToAllLogfiles(LogSeverity severity, const char* message, size_t len) { - if ( FLAGS_logtostderr ) // global flag: never log to file - WriteToStderr(message, len); - else + if ( FLAGS_logtostderr ) { // global flag: never log to file + ColoredWriteToStderr(severity, message, len); + } else { for (int i = severity; i >= 0; --i) LogDestination::MaybeLogToLogfile(i, timestamp, message, len); - + } } inline void LogDestination::LogToSinks(LogSeverity severity, @@ -691,7 +887,7 @@ void LogFileObject::FlushUnlocked(){ next_flush_time_ = CycleClock_Now() + UsecToCycles(next); } -bool LogFileObject::CreateLogfile(const char* time_pid_string) { +bool LogFileObject::CreateLogfile(const string& time_pid_string) { string string_filename = base_filename_+filename_extension_+ time_pid_string; const char* filename = string_filename.c_str(); @@ -724,8 +920,10 @@ bool LogFileObject::CreateLogfile(const char* time_pid_string) { linkpath += linkname; unlink(linkpath.c_str()); // delete old one if it exists +#if defined(OS_WINDOWS) + // TODO(hamaji): Create lnk file on Windows? +#elif defined(HAVE_UNISTD_H) // We must have unistd.h. -#ifdef HAVE_UNISTD_H // Make the symlink be relative (in the same dir) so that if the // entire log directory gets relocated the link is still valid. const char *linkdest = slash ? (slash + 1) : filename; @@ -779,24 +977,24 @@ void LogFileObject::Write(bool force_flush, localtime_r(×tamp, &tm_time); // The logfile's filename will have the date/time & pid in it - char time_pid_string[256]; // More than enough chars for time, pid, \0 - ostrstream time_pid_stream(time_pid_string, sizeof(time_pid_string)); + ostringstream time_pid_stream; time_pid_stream.fill('0'); time_pid_stream << 1900+tm_time.tm_year - << setw(2) << 1+tm_time.tm_mon - << setw(2) << tm_time.tm_mday - << '-' - << setw(2) << tm_time.tm_hour - << setw(2) << tm_time.tm_min - << setw(2) << tm_time.tm_sec - << '.' - << GetMainThreadPid() - << '\0'; + << setw(2) << 1+tm_time.tm_mon + << setw(2) << tm_time.tm_mday + << '-' + << setw(2) << tm_time.tm_hour + << setw(2) << tm_time.tm_min + << setw(2) << tm_time.tm_sec + << '.' + << GetMainThreadPid(); + const string& time_pid_string = time_pid_stream.str(); if (base_filename_selected_) { if (!CreateLogfile(time_pid_string)) { perror("Could not create log file"); - fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", time_pid_string); + fprintf(stderr, "COULD NOT CREATE LOGFILE '%s'!\n", + time_pid_string.c_str()); return; } } else { @@ -844,15 +1042,14 @@ void LogFileObject::Write(bool force_flush, // If we never succeeded, we have to give up if ( success == false ) { perror("Could not create logging file"); - fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", time_pid_string); + fprintf(stderr, "COULD NOT CREATE A LOGGINGFILE %s!", + time_pid_string.c_str()); return; } } // Write a header message into the log file - char file_header_string[512]; // Enough chars for time and binary info - ostrstream file_header_stream(file_header_string, - sizeof(file_header_string)); + ostringstream file_header_stream; file_header_stream.fill('0'); file_header_stream << "Log file created at: " << 1900+tm_time.tm_year << '/' @@ -865,10 +1062,11 @@ void LogFileObject::Write(bool force_flush, << "Running on machine: " << LogDestination::hostname() << '\n' << "Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu " - << "threadid file:line] msg" << '\n' - << '\0'; - int header_len = strlen(file_header_string); - fwrite(file_header_string, 1, header_len, file_); + << "threadid file:line] msg" << '\n'; + const string& file_header_string = file_header_stream.str(); + + const int header_len = file_header_string.size(); + fwrite(file_header_string.data(), 1, header_len, file_); file_length_ += header_len; bytes_since_flush_ += header_len; } @@ -916,9 +1114,6 @@ void LogFileObject::Write(bool force_flush, } // namespace -// An arbitrary limit on the length of a single log message. This -// is so that streaming can be done more efficiently. -const size_t LogMessage::kMaxLogMessageLen = 30000; // Static log data space to avoid alloc failures in a LOG(FATAL) // @@ -929,55 +1124,55 @@ const size_t LogMessage::kMaxLogMessageLen = 30000; static Mutex fatal_msg_lock; static CrashReason crash_reason; static bool fatal_msg_exclusive = true; -static char fatal_msg_buf_exclusive[LogMessage::kMaxLogMessageLen+1]; -static char fatal_msg_buf_shared[LogMessage::kMaxLogMessageLen+1]; -static LogMessage::LogStream fatal_msg_stream_exclusive( - fatal_msg_buf_exclusive, LogMessage::kMaxLogMessageLen, 0); -static LogMessage::LogStream fatal_msg_stream_shared( - fatal_msg_buf_shared, LogMessage::kMaxLogMessageLen, 0); -LogMessage::LogMessageData LogMessage::fatal_msg_data_exclusive_; -LogMessage::LogMessageData LogMessage::fatal_msg_data_shared_; +static LogMessage::LogMessageData fatal_msg_data_exclusive; +static LogMessage::LogMessageData fatal_msg_data_shared; -LogMessage::LogMessageData::~LogMessageData() { - delete[] buf_; - delete stream_alloc_; +LogMessage::LogMessageData::LogMessageData() + : stream_(message_text_, LogMessage::kMaxLogMessageLen, 0) { } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - int ctr, void (LogMessage::*send_method)()) { + int ctr, void (LogMessage::*send_method)()) + : allocated_(NULL) { Init(file, line, severity, send_method); - data_->stream_->set_ctr(ctr); + data_->stream_.set_ctr(ctr); } LogMessage::LogMessage(const char* file, int line, - const CheckOpString& result) { + const CheckOpString& result) + : allocated_(NULL) { Init(file, line, GLOG_FATAL, &LogMessage::SendToLog); stream() << "Check failed: " << (*result.str_) << " "; } -LogMessage::LogMessage(const char* file, int line) { +LogMessage::LogMessage(const char* file, int line) + : allocated_(NULL) { Init(file, line, GLOG_INFO, &LogMessage::SendToLog); } -LogMessage::LogMessage(const char* file, int line, LogSeverity severity) { +LogMessage::LogMessage(const char* file, int line, LogSeverity severity) + : allocated_(NULL) { Init(file, line, severity, &LogMessage::SendToLog); } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - LogSink* sink, bool also_send_to_log) { + LogSink* sink, bool also_send_to_log) + : allocated_(NULL) { Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : &LogMessage::SendToSink); data_->sink_ = sink; // override Init()'s setting to NULL } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - vector *outvec) { + vector *outvec) + : allocated_(NULL) { Init(file, line, severity, &LogMessage::SaveOrSendToLog); data_->outvec_ = outvec; // override Init()'s setting to NULL } LogMessage::LogMessage(const char* file, int line, LogSeverity severity, - string *message) { + string *message) + : allocated_(NULL) { Init(file, line, severity, &LogMessage::WriteToStringAndLog); data_->message_ = message; // override Init()'s setting to NULL } @@ -990,27 +1185,17 @@ void LogMessage::Init(const char* file, if (severity != GLOG_FATAL || !exit_on_dfatal) { allocated_ = new LogMessageData(); data_ = allocated_; - data_->buf_ = new char[kMaxLogMessageLen+1]; - data_->message_text_ = data_->buf_; - data_->stream_alloc_ = - new LogStream(data_->message_text_, kMaxLogMessageLen, 0); - data_->stream_ = data_->stream_alloc_; data_->first_fatal_ = false; } else { MutexLock l(&fatal_msg_lock); if (fatal_msg_exclusive) { fatal_msg_exclusive = false; - data_ = &fatal_msg_data_exclusive_; - data_->message_text_ = fatal_msg_buf_exclusive; - data_->stream_ = &fatal_msg_stream_exclusive; + data_ = &fatal_msg_data_exclusive; data_->first_fatal_ = true; } else { - data_ = &fatal_msg_data_shared_; - data_->message_text_ = fatal_msg_buf_shared; - data_->stream_ = &fatal_msg_stream_shared; + data_ = &fatal_msg_data_shared; data_->first_fatal_ = false; } - data_->stream_alloc_ = NULL; } stream().fill('0'); @@ -1051,7 +1236,7 @@ void LogMessage::Init(const char* file, << ' ' << data_->basename_ << ':' << data_->line_ << "] "; } - data_->num_prefix_chars_ = data_->stream_->pcount(); + data_->num_prefix_chars_ = data_->stream_.pcount(); if (!FLAGS_log_backtrace_at.empty()) { char fileline[128]; @@ -1071,13 +1256,21 @@ LogMessage::~LogMessage() { delete allocated_; } +int LogMessage::preserved_errno() const { + return data_->preserved_errno_; +} + +ostream& LogMessage::stream() { + return data_->stream_; +} + // Flush buffered message, called by the destructor, or any other function // that needs to synchronize the log. void LogMessage::Flush() { if (data_->has_been_flushed_ || data_->severity_ < FLAGS_minloglevel) return; - data_->num_chars_to_log_ = data_->stream_->pcount(); + data_->num_chars_to_log_ = data_->stream_.pcount(); data_->num_chars_to_syslog_ = data_->num_chars_to_log_ - data_->num_prefix_chars_; @@ -1127,7 +1320,7 @@ void LogMessage::Flush() { // Copy of first FATAL log message so that we can print it out again // after all the stack traces. To preserve legacy behavior, we don't -// use fatal_msg_buf_exclusive. +// use fatal_msg_data_exclusive. static time_t fatal_time; static char fatal_message[256]; @@ -1135,7 +1328,7 @@ void ReprintFatalMessage() { if (fatal_message[0]) { const int n = strlen(fatal_message); if (!FLAGS_logtostderr) { - // Also write to stderr + // Also write to stderr (don't color to avoid terminal checks) WriteToStderr(fatal_message, n); } LogDestination::LogToAllLogfiles(GLOG_ERROR, fatal_time, fatal_message, n); @@ -1164,7 +1357,8 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { // file if we haven't parsed the command line flags to get the // program name. if (FLAGS_logtostderr || !IsGoogleLoggingInitialized()) { - WriteToStderr(data_->message_text_, data_->num_chars_to_log_); + ColoredWriteToStderr(data_->severity_, + data_->message_text_, data_->num_chars_to_log_); // this could be protected by a flag if necessary. LogDestination::LogToSinks(data_->severity_, @@ -1236,10 +1430,10 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { void LogMessage::RecordCrashReason( glog_internal_namespace_::CrashReason* reason) { - reason->filename = fatal_msg_data_exclusive_.fullname_; - reason->line_number = fatal_msg_data_exclusive_.line_; - reason->message = fatal_msg_buf_exclusive + - fatal_msg_data_exclusive_.num_prefix_chars_; + reason->filename = fatal_msg_data_exclusive.fullname_; + reason->line_number = fatal_msg_data_exclusive.line_; + reason->message = fatal_msg_data_exclusive.message_text_ + + fatal_msg_data_exclusive.num_prefix_chars_; #ifdef HAVE_STACKTRACE // Retrieve the stack trace, omitting the logging frames that got us here. reason->depth = GetStackTrace(reason->stack, ARRAYSIZE(reason->stack), 4); @@ -1366,8 +1560,13 @@ int64 LogMessage::num_messages(int severity) { // Output the COUNTER value. This is only valid if ostream is a // LogStream. ostream& operator<<(ostream &os, const PRIVATE_Counter&) { +#ifdef DISABLE_RTTI + LogMessage::LogStream *log = static_cast(&os); +#else LogMessage::LogStream *log = dynamic_cast(&os); - CHECK(log == log->self()); +#endif + CHECK(log && log == log->self()) + << "You must not use COUNTER with non-glog ostream"; os << log->ctr(); return os; } @@ -1381,9 +1580,8 @@ ErrnoLogMessage::ErrnoLogMessage(const char* file, int line, ErrnoLogMessage::~ErrnoLogMessage() { // Don't access errno directly because it may have been altered // while streaming the message. - char buf[100]; - posix_strerror_r(preserved_errno(), buf, sizeof(buf)); - stream() << ": " << buf << " [" << preserved_errno() << "]"; + stream() << ": " << StrError(preserved_errno()) << " [" + << preserved_errno() << "]"; } void FlushLogFiles(LogSeverity min_severity) { @@ -1465,9 +1663,7 @@ void LogToStderr() { namespace base { namespace internal { -/* Put prototypes here to suppress strict compiler warnings */ -bool GetExitOnDFatal(); -void SetExitOnDFatal(bool value); +namespace { bool GetExitOnDFatal() { MutexLock l(&log_mutex); @@ -1489,6 +1685,8 @@ void SetExitOnDFatal(bool value) { exit_on_dfatal = value; } +} // namespace + } // namespace internal } // namespace base @@ -1516,13 +1714,11 @@ static bool SendEmailInternal(const char*dest, const char *subject, bool ok = pclose(pipe) != -1; if ( !ok ) { if ( use_logging ) { - char buf[100]; - posix_strerror_r(errno, buf, sizeof(buf)); - LOG(ERROR) << "Problems sending mail to " << dest << ": " << buf; + LOG(ERROR) << "Problems sending mail to " << dest << ": " + << StrError(errno); } else { - char buf[100]; - posix_strerror_r(errno, buf, sizeof(buf)); - fprintf(stderr, "Problems sending mail to %s: %s\n", dest, buf); + fprintf(stderr, "Problems sending mail to %s: %s\n", + dest, StrError(errno).c_str()); } } return ok; @@ -1644,8 +1840,11 @@ void TruncateLogFile(const char *path, int64 limit, int64 keep) { int64 read_offset, write_offset; // Don't follow symlinks unless they're our own fd symlinks in /proc int flags = O_RDWR; + // TODO(hamaji): Support other environments. +#ifdef OS_LINUX const char *procfd_prefix = "/proc/self/fd/"; if (strncmp(procfd_prefix, path, strlen(procfd_prefix))) flags |= O_NOFOLLOW; +#endif int fd = open(path, flags); if (fd == -1) { @@ -1730,11 +1929,11 @@ void TruncateStdoutStderr() { bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ if (equal == expected) return NULL; \ else { \ - strstream ss; \ + ostringstream ss; \ if (!s1) s1 = ""; \ if (!s2) s2 = ""; \ ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ - return new string(ss.str(), ss.pcount()); \ + return new string(ss.str()); \ } \ } DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) @@ -1793,6 +1992,15 @@ int posix_strerror_r(int err, char *buf, size_t len) { } } +string StrError(int err) { + char buf[100]; + int rc = posix_strerror_r(err, buf, sizeof(buf)); + if ((rc < 0) || (buf[0] == '\000')) { + snprintf(buf, sizeof(buf), "Error number %d", err); + } + return buf; +} + LogMessageFatal::LogMessageFatal(const char* file, int line) : LogMessage(file, line, GLOG_FATAL) {} @@ -1805,6 +2013,56 @@ LogMessageFatal::~LogMessageFatal() { LogMessage::Fail(); } +namespace base { + +CheckOpMessageBuilder::CheckOpMessageBuilder(const char *exprtext) + : stream_(new ostringstream) { + *stream_ << exprtext << " ("; +} + +CheckOpMessageBuilder::~CheckOpMessageBuilder() { + delete stream_; +} + +ostream* CheckOpMessageBuilder::ForVar2() { + *stream_ << " vs. "; + return stream_; +} + +string* CheckOpMessageBuilder::NewString() { + *stream_ << ")"; + return new string(stream_->str()); +} + +} // namespace base + +template <> +void MakeCheckOpValueString(std::ostream* os, const char& v) { + if (v >= 32 && v <= 126) { + (*os) << "'" << v << "'"; + } else { + (*os) << "char value " << (short)v; + } +} + +template <> +void MakeCheckOpValueString(std::ostream* os, const signed char& v) { + if (v >= 32 && v <= 126) { + (*os) << "'" << v << "'"; + } else { + (*os) << "signed char value " << (short)v; + } +} + +template <> +void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) { + if (v >= 32 && v <= 126) { + (*os) << "'" << v << "'"; + } else { + (*os) << "unsigned char value " << (unsigned short)v; + } +} + void InitGoogleLogging(const char* argv0) { glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); } diff --git a/extern/libmv/third_party/glog/src/raw_logging.cc b/extern/libmv/third_party/glog/src/raw_logging.cc index 42676cba5de..7a7409bbf34 100644 --- a/extern/libmv/third_party/glog/src/raw_logging.cc +++ b/extern/libmv/third_party/glog/src/raw_logging.cc @@ -42,8 +42,8 @@ #include // for open() #include #include "config.h" -#include // To pick up flag settings etc. -#include +#include "glog/logging.h" // To pick up flag settings etc. +#include "glog/raw_logging.h" #include "base/commandlineflags.h" #ifdef HAVE_STACKTRACE diff --git a/extern/libmv/third_party/glog/src/signalhandler.cc b/extern/libmv/third_party/glog/src/signalhandler.cc index e95e9e97274..cccd800d769 100644 --- a/extern/libmv/third_party/glog/src/signalhandler.cc +++ b/extern/libmv/third_party/glog/src/signalhandler.cc @@ -34,7 +34,7 @@ #include "utilities.h" #include "stacktrace.h" #include "symbolize.h" -#include +#include "glog/logging.h" #include #include @@ -48,6 +48,9 @@ _START_GOOGLE_NAMESPACE_ +// TOOD(hamaji): Use signal instead of sigaction? +#ifdef HAVE_SIGACTION + namespace { // We'll install the failure signal handler for these signals. We could @@ -330,7 +333,10 @@ void FailureSignalHandler(int signal_number, } // namespace +#endif // HAVE_SIGACTION + void InstallFailureSignalHandler() { +#ifdef HAVE_SIGACTION // Build the sigaction struct. struct sigaction sig_action; memset(&sig_action, 0, sizeof(sig_action)); @@ -341,10 +347,13 @@ void InstallFailureSignalHandler() { for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL)); } +#endif // HAVE_SIGACTION } void InstallFailureWriter(void (*writer)(const char* data, int size)) { +#ifdef HAVE_SIGACTION g_failure_writer = writer; +#endif // HAVE_SIGACTION } _END_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h index 46002c1b019..0dc14c6506e 100644 --- a/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h +++ b/extern/libmv/third_party/glog/src/stacktrace_libunwind-inl.h @@ -37,7 +37,7 @@ extern "C" { #define UNW_LOCAL_ONLY #include } -#include +#include "glog/raw_logging.h" #include "stacktrace.h" _START_GOOGLE_NAMESPACE_ diff --git a/extern/libmv/third_party/glog/src/symbolize.cc b/extern/libmv/third_party/glog/src/symbolize.cc index d1831e4ea79..18bbccf3072 100644 --- a/extern/libmv/third_party/glog/src/symbolize.cc +++ b/extern/libmv/third_party/glog/src/symbolize.cc @@ -111,7 +111,7 @@ _END_GOOGLE_NAMESPACE_ #include "symbolize.h" #include "config.h" -#include +#include "glog/raw_logging.h" // Re-runs fn until it doesn't cause EINTR. #define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR) @@ -232,7 +232,7 @@ bool GetSectionHeaderByName(int fd, const char *name, size_t name_len, } char header_name[kMaxSectionNameLen]; if (sizeof(header_name) < name_len) { - RAW_LOG(WARNING, "Section name '%s' is too long (%"PRIuS"); " + RAW_LOG(WARNING, "Section name '%s' is too long (%" PRIuS "); " "section will not be found (even if present).", name, name_len); // No point in even trying. return false; diff --git a/extern/libmv/third_party/glog/src/symbolize.h b/extern/libmv/third_party/glog/src/symbolize.h index 04e482bc315..1ebe4dd94a2 100644 --- a/extern/libmv/third_party/glog/src/symbolize.h +++ b/extern/libmv/third_party/glog/src/symbolize.h @@ -56,7 +56,7 @@ #include "utilities.h" #include "config.h" -#include +#include "glog/logging.h" #ifdef HAVE_SYMBOLIZE diff --git a/extern/libmv/third_party/glog/src/utilities.cc b/extern/libmv/third_party/glog/src/utilities.cc index 159b094c170..1e8836d243f 100644 --- a/extern/libmv/third_party/glog/src/utilities.cc +++ b/extern/libmv/third_party/glog/src/utilities.cc @@ -136,6 +136,8 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) { static void DumpStackTraceAndExit() { DumpStackTrace(1, DebugWriteToStderr, NULL); + // TOOD(hamaji): Use signal instead of sigaction? +#ifdef HAVE_SIGACTION // Set the default signal handler for SIGABRT, to avoid invoking our // own signal handler installed by InstallFailedSignalHandler(). struct sigaction sig_action; @@ -143,6 +145,7 @@ static void DumpStackTraceAndExit() { sigemptyset(&sig_action.sa_mask); sig_action.sa_handler = SIG_DFL; sigaction(SIGABRT, &sig_action, NULL); +#endif // HAVE_SIGACTION abort(); } @@ -233,7 +236,7 @@ bool PidHasChanged() { } pid_t GetTID() { - // On Linux and MACOSX , we try to use gettid(). + // On Linux and MacOSX, we try to use gettid(). #if defined OS_LINUX || defined OS_MACOSX #ifndef __NR_gettid #ifdef OS_MACOSX @@ -331,6 +334,7 @@ void InitGoogleLoggingUtilities(const char* argv0) { void ShutdownGoogleLoggingUtilities() { CHECK(IsGoogleLoggingInitialized()) << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!"; + g_program_invocation_short_name = NULL; #ifdef HAVE_SYSLOG_H closelog(); #endif diff --git a/extern/libmv/third_party/glog/src/utilities.h b/extern/libmv/third_party/glog/src/utilities.h index c8215b73f33..4f41c92e434 100644 --- a/extern/libmv/third_party/glog/src/utilities.h +++ b/extern/libmv/third_party/glog/src/utilities.h @@ -79,7 +79,7 @@ #endif #include "config.h" -#include +#include "glog/logging.h" // There are three different ways we can try to get the stack trace: // @@ -108,7 +108,7 @@ #elif !defined(NO_FRAME_POINTER) # if defined(__i386__) && __GNUC__ >= 2 # define STACKTRACE_H "stacktrace_x86-inl.h" -# elif defined(__x86_64__) && __GNUC__ >= 2 +# elif defined(__x86_64__) && __GNUC__ >= 2 && HAVE_UNWIND_H # define STACKTRACE_H "stacktrace_x86_64-inl.h" # elif (defined(__ppc__) || defined(__PPC__)) && __GNUC__ >= 2 # define STACKTRACE_H "stacktrace_powerpc-inl.h" diff --git a/extern/libmv/third_party/glog/src/vlog_is_on.cc b/extern/libmv/third_party/glog/src/vlog_is_on.cc index 4396aa8d066..cd7fc19bca8 100644 --- a/extern/libmv/third_party/glog/src/vlog_is_on.cc +++ b/extern/libmv/third_party/glog/src/vlog_is_on.cc @@ -40,8 +40,8 @@ #include #include #include "base/commandlineflags.h" -#include -#include +#include "glog/logging.h" +#include "glog/raw_logging.h" #include "base/googleinit.h" // glog doesn't have annotation @@ -62,11 +62,7 @@ _START_GOOGLE_NAMESPACE_ namespace glog_internal_namespace_ { -// Put protytype here to suppress strict compiler flags -GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, - size_t patt_len, - const char* str, - size_t str_len); +namespace { // Implementation of fnmatch that does not need 0-termination // of arguments and does not allocate any memory, @@ -101,6 +97,8 @@ GOOGLE_GLOG_DLL_DECL bool SafeFNMatch_(const char* pattern, } } +} // namespace + } // namespace glog_internal_namespace_ using glog_internal_namespace_::SafeFNMatch_; diff --git a/extern/libmv/third_party/glog/src/windows/config.h b/extern/libmv/third_party/glog/src/windows/config.h index 682a1b9309d..9fb3cc564d5 100644 --- a/extern/libmv/third_party/glog/src/windows/config.h +++ b/extern/libmv/third_party/glog/src/windows/config.h @@ -1,122 +1,10 @@ /* src/config.h.in. Generated from configure.ac by autoheader. */ -/* Namespace for Google classes */ -#define GOOGLE_NAMESPACE google - -/* Define if you have the `dladdr' function */ -#undef HAVE_DLADDR - -/* Define to 1 if you have the header file. */ -#undef HAVE_DLFCN_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_EXECINFO_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_INTTYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_LIBUNWIND_H - /* define if you have google gflags library */ #define HAVE_LIB_GFLAGS 1 -/* define if you have libunwind */ -#undef HAVE_LIB_UNWIND - -/* Define to 1 if you have the header file. */ -#undef HAVE_MEMORY_H - -/* define if the compiler implements namespaces */ -#undef HAVE_NAMESPACES - -/* Define if you have POSIX threads libraries and header files. */ -#undef HAVE_PTHREAD - -/* define if the compiler implements pthread_rwlock_* */ -#undef HAVE_RWLOCK - -/* Define if you have the `sigaltstack' function */ -#undef HAVE_SIGALTSTACK - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDINT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STDLIB_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRINGS_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_STRING_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_STAT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_SYSCALL_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_SYS_TYPES_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UCONTEXT_H - -/* Define to 1 if you have the header file. */ -#undef HAVE_UNISTD_H - -/* define if the compiler supports using expression for operator */ -#undef HAVE_USING_OPERATOR - -/* define if your compiler has __attribute__ */ -#undef HAVE___ATTRIBUTE__ - -/* define if your compiler has __builtin_expect */ -#undef HAVE___BUILTIN_EXPECT - -/* define if your compiler has __sync_val_compare_and_swap */ -#undef HAVE___SYNC_VAL_COMPARE_AND_SWAP - -/* Name of package */ -#undef PACKAGE - -/* Define to the address where bug reports for this package should be sent. */ -#undef PACKAGE_BUGREPORT - -/* Define to the full name of this package. */ -#undef PACKAGE_NAME - -/* Define to the full name and version of this package. */ -#undef PACKAGE_STRING - -/* Define to the one symbol short name of this package. */ -#undef PACKAGE_TARNAME - -/* Define to the version of this package. */ -#undef PACKAGE_VERSION - -/* How to access the PC from a struct ucontext */ -#undef PC_FROM_UCONTEXT - -/* Define to necessary symbol if this constant uses a non-standard name on - your system. */ -#undef PTHREAD_CREATE_JOINABLE - -/* The size of `void *', as computed by sizeof. */ -#undef SIZEOF_VOID_P - -/* Define to 1 if you have the ANSI C header files. */ -#undef STDC_HEADERS - -/* the namespace where STL code like vector<> is defined */ -#undef STL_NAMESPACE - -/* Version number of package */ -#undef VERSION +/* Namespace for Google classes */ +#define GOOGLE_NAMESPACE google /* Stops putting the code inside the Google namespace */ #define _END_GOOGLE_NAMESPACE_ } diff --git a/extern/libmv/third_party/glog/src/windows/glog/logging.h b/extern/libmv/third_party/glog/src/windows/glog/logging.h index f623cd9e793..6e9c9224f92 100644 --- a/extern/libmv/third_party/glog/src/windows/glog/logging.h +++ b/extern/libmv/third_party/glog/src/windows/glog/logging.h @@ -43,18 +43,13 @@ #include #include #include +#include +#include +#include #include #if 0 # include #endif -#ifdef __DEPRECATED -// Make GCC quiet. -# undef __DEPRECATED -# include -# define __DEPRECATED -#else -# include -#endif #include // Annoying stuff for windows -- makes sure clients can import these functions @@ -65,6 +60,14 @@ # define GOOGLE_GLOG_DLL_DECL # endif #endif +#if defined(_MSC_VER) +#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) __pragma(warning(push)) \ + __pragma(warning(disable:n)) +#define GLOG_MSVC_POP_WARNING() __pragma(warning(pop)) +#else +#define GLOG_MSVC_PUSH_DISABLE_WARNING(n) +#define GLOG_MSVC_POP_WARNING() +#endif // We care a lot about number of bits things take up. Unfortunately, // systems define their bit-specific ints in a lot of different ways. @@ -83,7 +86,7 @@ #endif #if 1 -#include "third_party/gflags/gflags/gflags.h" +#include #endif #ifdef __MINGW32__ @@ -97,7 +100,7 @@ namespace google { -#if 0 // the C99 format +#if defined(__MINGW32__) // the C99 format typedef int32_t int32; typedef uint32_t uint32; typedef int64_t int64; @@ -107,16 +110,11 @@ typedef int32_t int32; typedef u_int32_t uint32; typedef int64_t int64; typedef u_int64_t uint64; -#elif defined(_MSC_VER) +#elif defined(_MSC_VER) // the windows (vc7) format typedef __int32 int32; typedef unsigned __int32 uint32; typedef __int64 int64; typedef unsigned __int64 uint64; -#elif defined(__MINGW32__) -typedef int32_t int32; -typedef uint32_t uint32; -typedef int64_t int64; -typedef uint64_t uint64; #else #error Do not know how to define a 32-bit integer quantity on your system #endif @@ -144,8 +142,12 @@ typedef uint64_t uint64; #ifndef GOOGLE_PREDICT_BRANCH_NOT_TAKEN #if 0 #define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) (__builtin_expect(x, 0)) +#define GOOGLE_PREDICT_FALSE(x) (__builtin_expect(x, 0)) +#define GOOGLE_PREDICT_TRUE(x) (__builtin_expect(!!(x), 1)) #else #define GOOGLE_PREDICT_BRANCH_NOT_TAKEN(x) x +#define GOOGLE_PREDICT_FALSE(x) x +#define GOOGLE_PREDICT_TRUE(x) x #endif #endif @@ -304,27 +306,27 @@ typedef uint64_t uint64; #ifndef DECLARE_VARIABLE #define MUST_UNDEF_GFLAGS_DECLARE_MACROS -#define DECLARE_VARIABLE(type, name, tn) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead { \ - extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_##tn##_instead::FLAGS_##name +#define DECLARE_VARIABLE(type, shorttype, name, tn) \ + namespace fL##shorttype { \ + extern GOOGLE_GLOG_DLL_DECL type FLAGS_##name; \ + } \ + using fL##shorttype::FLAGS_##name // bool specialization #define DECLARE_bool(name) \ - DECLARE_VARIABLE(bool, name, bool) + DECLARE_VARIABLE(bool, B, name, bool) // int32 specialization #define DECLARE_int32(name) \ - DECLARE_VARIABLE(google::int32, name, int32) + DECLARE_VARIABLE(google::int32, I, name, int32) // Special case for string, because we have to specify the namespace // std::string, which doesn't play nicely with our FLAG__namespace hackery. -#define DECLARE_string(name) \ - namespace FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead { \ - extern GOOGLE_GLOG_DLL_DECL std::string FLAGS_##name; \ - } \ - using FLAG__namespace_do_not_use_directly_use_DECLARE_string_instead::FLAGS_##name +#define DECLARE_string(name) \ + namespace fLS { \ + extern GOOGLE_GLOG_DLL_DECL std::string& FLAGS_##name; \ + } \ + using fLS::FLAGS_##name #endif // Set whether log messages go to stderr instead of logfiles @@ -333,6 +335,9 @@ DECLARE_bool(logtostderr); // Set whether log messages go to stderr in addition to logfiles. DECLARE_bool(alsologtostderr); +// Set color messages logged to stderr (if supported by terminal). +DECLARE_bool(colorlogtostderr); + // Log messages at a level >= this flag are automatically sent to // stderr in addition to log files. DECLARE_int32(stderrthreshold); @@ -465,15 +470,16 @@ DECLARE_bool(stop_logging_if_full_disk); #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__CYGWIN__) || defined(__CYGWIN32__) // A very useful logging macro to log windows errors: #define LOG_SYSRESULT(result) \ - if (FAILED(result)) { \ - LPTSTR message = NULL; \ - LPTSTR msg = reinterpret_cast(&message); \ - DWORD message_length = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ + if (FAILED(HRESULT_FROM_WIN32(result))) { \ + LPSTR message = NULL; \ + LPSTR msg = reinterpret_cast(&message); \ + DWORD message_length = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | \ FORMAT_MESSAGE_FROM_SYSTEM, \ 0, result, 0, msg, 100, NULL); \ if (message_length > 0) { \ google::LogMessage(__FILE__, __LINE__, google::GLOG_ERROR, 0, \ - &google::LogMessage::SendToLog).stream() << message; \ + &google::LogMessage::SendToLog).stream() \ + << reinterpret_cast(message); \ LocalFree(message); \ } \ } @@ -615,18 +621,68 @@ inline std::ostream& operator<<( namespace google { -// Build the error message string. -template -std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { - // It means that we cannot use stl_logging if compiler doesn't - // support using expression for operator. - // TODO(hamaji): Figure out a way to fix. -#if 1 - using ::operator<<; -#endif - std::strstream ss; - ss << names << " (" << v1 << " vs. " << v2 << ")"; - return new std::string(ss.str(), ss.pcount()); +// This formats a value for a failing CHECK_XX statement. Ordinarily, +// it uses the definition for operator<<, with a few special cases below. +template +inline void MakeCheckOpValueString(std::ostream* os, const T& v) { + (*os) << v; +} + +// Overrides for char types provide readable values for unprintable +// characters. +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const char& v); +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const signed char& v); +template <> GOOGLE_GLOG_DLL_DECL +void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); + +// Build the error message string. Specify no inlining for code size. +template +std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) + ; + +namespace base { +namespace internal { + +// If "s" is less than base_logging::INFO, returns base_logging::INFO. +// If "s" is greater than base_logging::FATAL, returns +// base_logging::ERROR. Otherwise, returns "s". +LogSeverity NormalizeSeverity(LogSeverity s); + +} // namespace internal + +// A helper class for formatting "expr (V1 vs. V2)" in a CHECK_XX +// statement. See MakeCheckOpString for sample usage. Other +// approaches were considered: use of a template method (e.g., +// base::BuildCheckOpString(exprtext, base::Print, &v1, +// base::Print, &v2), however this approach has complications +// related to volatile arguments and function-pointer arguments). +class GOOGLE_GLOG_DLL_DECL CheckOpMessageBuilder { + public: + // Inserts "exprtext" and " (" to the stream. + explicit CheckOpMessageBuilder(const char *exprtext); + // Deletes "stream_". + ~CheckOpMessageBuilder(); + // For inserting the first variable. + std::ostream* ForVar1() { return stream_; } + // For inserting the second variable (adds an intermediate " vs. "). + std::ostream* ForVar2(); + // Get the result (inserts the closing ")"). + std::string* NewString(); + + private: + std::ostringstream *stream_; +}; + +} // namespace base + +template +std::string* MakeCheckOpString(const T1& v1, const T2& v2, const char* exprtext) { + base::CheckOpMessageBuilder comb(exprtext); + MakeCheckOpValueString(comb.ForVar1(), v1); + MakeCheckOpValueString(comb.ForVar2(), v2); + return comb.NewString(); } // Helper functions for CHECK_OP macro. @@ -634,26 +690,26 @@ std::string* MakeCheckOpString(const t1& v1, const t2& v2, const char* names) { // will not instantiate the template version of the function on values of // unnamed enum type - see comment below. #define DEFINE_CHECK_OP_IMPL(name, op) \ - template \ - inline std::string* Check##name##Impl(const t1& v1, const t2& v2, \ - const char* names) { \ - if (v1 op v2) return NULL; \ - else return MakeCheckOpString(v1, v2, names); \ + template \ + inline std::string* name##Impl(const T1& v1, const T2& v2, \ + const char* exprtext) { \ + if (GOOGLE_PREDICT_TRUE(v1 op v2)) return NULL; \ + else return MakeCheckOpString(v1, v2, exprtext); \ } \ - inline std::string* Check##name##Impl(int v1, int v2, const char* names) { \ - return Check##name##Impl(v1, v2, names); \ + inline std::string* name##Impl(int v1, int v2, const char* exprtext) { \ + return name##Impl(v1, v2, exprtext); \ } -// Use _EQ, _NE, _LE, etc. in case the file including base/logging.h -// provides its own #defines for the simpler names EQ, NE, LE, etc. +// We use the full name Check_EQ, Check_NE, etc. in case the file including +// base/logging.h provides its own #defines for the simpler names EQ, NE, etc. // This happens if, for example, those are used as token names in a // yacc grammar. -DEFINE_CHECK_OP_IMPL(_EQ, ==) -DEFINE_CHECK_OP_IMPL(_NE, !=) -DEFINE_CHECK_OP_IMPL(_LE, <=) -DEFINE_CHECK_OP_IMPL(_LT, < ) -DEFINE_CHECK_OP_IMPL(_GE, >=) -DEFINE_CHECK_OP_IMPL(_GT, > ) +DEFINE_CHECK_OP_IMPL(Check_EQ, ==) // Compilation error with CHECK_EQ(NULL, x)? +DEFINE_CHECK_OP_IMPL(Check_NE, !=) // Use CHECK(x == NULL) instead. +DEFINE_CHECK_OP_IMPL(Check_LE, <=) +DEFINE_CHECK_OP_IMPL(Check_LT, < ) +DEFINE_CHECK_OP_IMPL(Check_GE, >=) +DEFINE_CHECK_OP_IMPL(Check_GT, > ) #undef DEFINE_CHECK_OP_IMPL // Helper macro for binary operators. @@ -958,52 +1014,65 @@ const LogSeverity GLOG_0 = GLOG_ERROR; #define DLOG_ASSERT(condition) \ true ? (void) 0 : LOG_ASSERT(condition) +// MSVC warning C4127: conditional expression is constant #define DCHECK(condition) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK(condition) + GLOG_MSVC_POP_WARNING() CHECK(condition) #define DCHECK_EQ(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_EQ(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_EQ(val1, val2) #define DCHECK_NE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_NE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_NE(val1, val2) #define DCHECK_LE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_LE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_LE(val1, val2) #define DCHECK_LT(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_LT(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_LT(val1, val2) #define DCHECK_GE(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_GE(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_GE(val1, val2) #define DCHECK_GT(val1, val2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_GT(val1, val2) + GLOG_MSVC_POP_WARNING() CHECK_GT(val1, val2) +// You may see warnings in release mode if you don't use the return +// value of DCHECK_NOTNULL. Please just use DCHECK for such cases. #define DCHECK_NOTNULL(val) (val) #define DCHECK_STREQ(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STREQ(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STREQ(str1, str2) #define DCHECK_STRCASEEQ(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRCASEEQ(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STRCASEEQ(str1, str2) #define DCHECK_STRNE(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRNE(str1, str2) + GLOG_MSVC_POP_WARNING() CHECK_STRNE(str1, str2) #define DCHECK_STRCASENE(str1, str2) \ + GLOG_MSVC_PUSH_DISABLE_WARNING(4127) \ while (false) \ - CHECK_STRCASENE(str1, str2) - + GLOG_MSVC_POP_WARNING() CHECK_STRCASENE(str1, str2) #endif // NDEBUG @@ -1020,6 +1089,29 @@ const LogSeverity GLOG_0 = GLOG_ERROR; #define VLOG_IF_EVERY_N(verboselevel, condition, n) \ LOG_IF_EVERY_N(INFO, (condition) && VLOG_IS_ON(verboselevel), n) +namespace base_logging { + +// LogMessage::LogStream is a std::ostream backed by this streambuf. +// This class ignores overflow and leaves two bytes at the end of the +// buffer to allow for a '\n' and '\0'. +class GOOGLE_GLOG_DLL_DECL LogStreamBuf : public std::streambuf { + public: + // REQUIREMENTS: "len" must be >= 2 to account for the '\n' and '\n'. + LogStreamBuf(char *buf, int len) { + setp(buf, buf + len - 2); + } + // This effectively ignores overflow. + virtual int_type overflow(int_type ch) { + return ch; + } + + // Legacy public ostrstream method. + size_t pcount() const { return pptr() - pbase(); } + char* pbase() const { return std::streambuf::pbase(); } +}; + +} // namespace base_logging + // // This class more or less represents a particular log message. You // create an instance of LogMessage and then stream stuff to it. @@ -1049,22 +1141,30 @@ public: #ifdef _MSC_VER # pragma warning(disable: 4275) #endif - class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostrstream { + class GOOGLE_GLOG_DLL_DECL LogStream : public std::ostream { #ifdef _MSC_VER # pragma warning(default: 4275) #endif public: - LogStream(char *buf, int len, int ctr_in) - : ostrstream(buf, len), - ctr_(ctr_in) { - self_ = this; + LogStream(char *buf, int len, int ctr) + : std::ostream(NULL), + streambuf_(buf, len), + ctr_(ctr), + self_(this) { + rdbuf(&streambuf_); } int ctr() const { return ctr_; } - void set_ctr(int ctr_in) { ctr_ = ctr_in; } + void set_ctr(int ctr) { ctr_ = ctr; } LogStream* self() const { return self_; } + // Legacy std::streambuf methods. + size_t pcount() const { return streambuf_.pcount(); } + char* pbase() const { return streambuf_.pbase(); } + char* str() const { return pbase(); } + private: + base_logging::LogStreamBuf streambuf_; int ctr_; // Counter hack (for the LOG_EVERY_X() macro) LogStream *self_; // Consistency check hack }; @@ -1133,13 +1233,15 @@ public: // Call abort() or similar to perform LOG(FATAL) crash. static void Fail() ; - std::ostream& stream() { return *(data_->stream_); } + std::ostream& stream(); - int preserved_errno() const { return data_->preserved_errno_; } + int preserved_errno() const; // Must be called without the log_mutex held. (L < log_mutex) static int64 num_messages(int severity); + struct LogMessageData; + private: // Fully internal SendMethod cases: void SendToSinkAndLog(); // Send to sink if provided and dispatch to the logs @@ -1161,41 +1263,6 @@ private: // We keep the data in a separate struct so that each instance of // LogMessage uses less stack space. - struct GOOGLE_GLOG_DLL_DECL LogMessageData { - LogMessageData() {}; - - int preserved_errno_; // preserved errno - char* buf_; - char* message_text_; // Complete message text (points to selected buffer) - LogStream* stream_alloc_; - LogStream* stream_; - char severity_; // What level is this LogMessage logged at? - int line_; // line number where logging call is. - void (LogMessage::*send_method_)(); // Call this in destructor to send - union { // At most one of these is used: union to keep the size low. - LogSink* sink_; // NULL or sink to send message to - std::vector* outvec_; // NULL or vector to push message onto - std::string* message_; // NULL or string to write message into - }; - time_t timestamp_; // Time of creation of LogMessage - struct ::tm tm_time_; // Time of creation of LogMessage - size_t num_prefix_chars_; // # of chars of prefix in this message - size_t num_chars_to_log_; // # of chars of msg to send to log - size_t num_chars_to_syslog_; // # of chars of msg to send to syslog - const char* basename_; // basename of file that called LOG - const char* fullname_; // fullname of file that called LOG - bool has_been_flushed_; // false => data has not been flushed - bool first_fatal_; // true => this was first fatal msg - - ~LogMessageData(); - private: - LogMessageData(const LogMessageData&); - void operator=(const LogMessageData&); - }; - - static LogMessageData fatal_msg_data_exclusive_; - static LogMessageData fatal_msg_data_shared_; - LogMessageData* allocated_; LogMessageData* data_; @@ -1474,8 +1541,12 @@ extern GOOGLE_GLOG_DLL_DECL void SetLogger(LogSeverity level, Logger* logger); // be set to an empty string, if this function failed. This means, in most // cases, you do not need to check the error code and you can directly // use the value of "buf". It will never have an undefined value. +// DEPRECATED: Use StrError(int) instead. GOOGLE_GLOG_DLL_DECL int posix_strerror_r(int err, char *buf, size_t len); +// A thread-safe replacement for strerror(). Returns a string describing the +// given POSIX error code. +GOOGLE_GLOG_DLL_DECL std::string StrError(int err); // A class for which we define operator<<, which does nothing. class GOOGLE_GLOG_DLL_DECL NullStream : public LogMessage::LogStream { diff --git a/extern/libmv/third_party/glog/src/windows/port.cc b/extern/libmv/third_party/glog/src/windows/port.cc index 58e28b026c0..c16111a4b6d 100644 --- a/extern/libmv/third_party/glog/src/windows/port.cc +++ b/extern/libmv/third_party/glog/src/windows/port.cc @@ -55,7 +55,6 @@ int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { return _vsnprintf(str, size-1, format, ap); } -// MinGW64 defines #ifndef __MINGW64__ int snprintf(char *str, size_t size, const char *format, ...) { va_list ap; diff --git a/extern/libmv/third_party/glog/src/windows/port.h b/extern/libmv/third_party/glog/src/windows/port.h index e3e76ec29e0..4879cbf5f92 100644 --- a/extern/libmv/third_party/glog/src/windows/port.h +++ b/extern/libmv/third_party/glog/src/windows/port.h @@ -45,7 +45,10 @@ #ifdef _WIN32 +#ifndef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN /* We always want minimal includes */ +#endif + #include #include /* for gethostname */ #include /* because we so often use open/close/etc */ @@ -59,6 +62,8 @@ * used by both C and C++ code, so we put all the C++ together. */ +#ifdef _MSC_VER + /* 4244: otherwise we get problems when substracting two size_t's to an int * 4251: it's complaining about a private struct I've chosen not to dllexport * 4355: we use this in a constructor, but we do it safely @@ -111,9 +116,7 @@ extern int snprintf(char *str, size_t size, extern int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap); #define vsnprintf(str, size, format, ap) safe_vsnprintf(str, size, format, ap) -#if !defined(__MINGW32__) #define va_copy(dst, src) (dst) = (src) -#endif /* Windows doesn't support specifying the number of buckets as a * hash_map constructor arg, so we leave this blank. @@ -123,11 +126,14 @@ extern int safe_vsnprintf(char *str, size_t size, #define DEFAULT_TEMPLATE_ROOTDIR ".." // ----------------------------------- SYSTEM/PROCESS -#ifndef __MINGW64__ typedef int pid_t; -#endif #define getpid _getpid +#include +typedef SSIZE_T ssize_t; + +#endif // _MSC_VER + // ----------------------------------- THREADS typedef DWORD pthread_t; typedef DWORD pthread_key_t;