move to C++14 (#902)

This commit is contained in:
Sergiu Deitsch 2023-02-28 12:26:49 +01:00 committed by GitHub
parent 35f4efbb0a
commit 6742834201
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 643 additions and 1348 deletions

View File

@ -157,7 +157,7 @@ SpacesInCStyleCastParentheses: false
SpacesInParentheses: false SpacesInParentheses: false
SpacesInSquareBrackets: false SpacesInSquareBrackets: false
SpaceBeforeSquareBrackets: false SpaceBeforeSquareBrackets: false
Standard: Auto Standard: c++14
StatementMacros: StatementMacros:
- Q_UNUSED - Q_UNUSED
- QT_REQUIRE_VERSION - QT_REQUIRE_VERSION

View File

@ -1,5 +1,5 @@
--- ---
Checks: 'clang-diagnostic-*,clang-analyzer-*,google-*' Checks: 'clang-diagnostic-*,clang-analyzer-*,google-*,modernize-*,-modernize-use-trailing-return-type,readability-*,portability-*,performance-*,bugprone-*,android-*,darwin-*,clang-analyzer-*'
WarningsAsErrors: '' WarningsAsErrors: ''
HeaderFilterRegex: '' HeaderFilterRegex: ''
AnalyzeTemporaryDtors: false AnalyzeTemporaryDtors: false

View File

@ -14,7 +14,7 @@ jobs:
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
std: [98, 11, 14, 17, 20] std: [14, 17, 20]
abi: [arm64-v8a, armeabi-v7a, x86_64, x86] abi: [arm64-v8a, armeabi-v7a, x86_64, x86]
build_type: [Debug, Release] build_type: [Debug, Release]
@ -26,11 +26,6 @@ jobs:
with: with:
version: 1.10.0 version: 1.10.0
- name: Setup C++98 Environment
if: matrix.std == '98'
run: |
echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
- name: Setup NDK - name: Setup NDK
env: env:
ANDROID_SDK_ROOT: /usr/local/lib/android/sdk ANDROID_SDK_ROOT: /usr/local/lib/android/sdk

View File

@ -15,7 +15,7 @@ jobs:
matrix: matrix:
build_type: [Release, Debug] build_type: [Release, Debug]
lib: [static] lib: [static]
std: [98, 11, 14, 17, 20] std: [14, 17, 20]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -27,11 +27,6 @@ jobs:
cmake \ cmake \
ninja-build ninja-build
- name: Setup C++98 Environment
if: matrix.std == '98'
run: |
echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
- name: Configure - name: Configure
env: env:
CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror -Wno-error=wasm-exception-spec ${{env.CXXFLAGS}} CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror -Wno-error=wasm-exception-spec ${{env.CXXFLAGS}}

View File

@ -14,7 +14,7 @@ jobs:
matrix: matrix:
build_type: [Release, Debug] build_type: [Release, Debug]
lib: [shared, static] lib: [shared, static]
std: [98, 11, 14, 17, 20] std: [14, 17, 20]
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v3
@ -59,11 +59,6 @@ jobs:
echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV echo 'CXXFLAGS=--coverage' >> $GITHUB_ENV
echo 'GTest_ROOT=${{github.workspace}}/gtest' >> $GITHUB_ENV echo 'GTest_ROOT=${{github.workspace}}/gtest' >> $GITHUB_ENV
- name: Setup C++98 Environment
if: matrix.std == '98'
run: |
echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
- name: Configure - name: Configure
env: env:
CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}} CXXFLAGS: -Wall -Wextra -Wsign-conversion -Wtautological-compare -Wformat-nonliteral -Wundef -Werror ${{env.CXXFLAGS}}

View File

@ -9,7 +9,7 @@ jobs:
strategy: strategy:
fail-fast: true fail-fast: true
matrix: matrix:
std: [98, 11, 14, 17, 20] std: [14, 17, 20]
include: include:
- generator: Ninja - generator: Ninja
- build_type: Debug - build_type: Debug

View File

@ -19,7 +19,6 @@ jobs:
build_type: [Debug, Release] build_type: [Debug, Release]
lib: [shared, static] lib: [shared, static]
msvc: [VS-16-2019, VS-17-2022] msvc: [VS-16-2019, VS-17-2022]
# Visual Studio 17 2022 does not support C++11 and older language standard
std: [14, 17, 20] std: [14, 17, 20]
include: include:
- msvc: VS-16-2019 - msvc: VS-16-2019
@ -139,7 +138,7 @@ jobs:
matrix: matrix:
build_type: [Debug] build_type: [Debug]
lib: [shared, static] lib: [shared, static]
std: [98, 11, 14, 17, 20] std: [14, 17, 20]
sys: [mingw32, mingw64] sys: [mingw32, mingw64]
include: include:
- sys: mingw32 - sys: mingw32
@ -159,11 +158,6 @@ jobs:
mingw-w64-${{matrix.env}}-gflags mingw-w64-${{matrix.env}}-gflags
mingw-w64-${{matrix.env}}-ninja mingw-w64-${{matrix.env}}-ninja
- name: Setup C++98 Environment
if: matrix.std == '98'
run: |
echo 'CXXFLAGS=-Wno-error=variadic-macros -Wno-error=long-long ${{env.CXXFLAGS}}' >> $GITHUB_ENV
- name: Setup Environment - name: Setup Environment
if: matrix.build_type == 'Debug' if: matrix.build_type == 'Debug'
run: | run: |

View File

@ -104,10 +104,8 @@ endif (Unwind_FOUND)
check_include_file_cxx (dlfcn.h HAVE_DLFCN_H) check_include_file_cxx (dlfcn.h HAVE_DLFCN_H)
check_include_file_cxx (glob.h HAVE_GLOB_H) check_include_file_cxx (glob.h HAVE_GLOB_H)
check_include_file_cxx (inttypes.h HAVE_INTTYPES_H)
check_include_file_cxx (memory.h HAVE_MEMORY_H) check_include_file_cxx (memory.h HAVE_MEMORY_H)
check_include_file_cxx (pwd.h HAVE_PWD_H) check_include_file_cxx (pwd.h HAVE_PWD_H)
check_include_file_cxx (stdint.h HAVE_STDINT_H)
check_include_file_cxx (strings.h HAVE_STRINGS_H) check_include_file_cxx (strings.h HAVE_STRINGS_H)
check_include_file_cxx (sys/stat.h HAVE_SYS_STAT_H) check_include_file_cxx (sys/stat.h HAVE_SYS_STAT_H)
check_include_file_cxx (sys/syscall.h HAVE_SYS_SYSCALL_H) check_include_file_cxx (sys/syscall.h HAVE_SYS_SYSCALL_H)
@ -120,19 +118,8 @@ check_include_file_cxx (syslog.h HAVE_SYSLOG_H)
check_include_file_cxx (ucontext.h HAVE_UCONTEXT_H) check_include_file_cxx (ucontext.h HAVE_UCONTEXT_H)
check_include_file_cxx (unistd.h HAVE_UNISTD_H) check_include_file_cxx (unistd.h HAVE_UNISTD_H)
check_include_file_cxx ("ext/hash_map" HAVE_EXT_HASH_MAP)
check_include_file_cxx ("ext/hash_set" HAVE_EXT_HASH_SET)
check_include_file_cxx ("ext/slist" HAVE_EXT_SLIST)
check_include_file_cxx ("tr1/unordered_map" HAVE_TR1_UNORDERED_MAP)
check_include_file_cxx ("tr1/unordered_set" HAVE_TR1_UNORDERED_SET)
check_include_file_cxx ("unordered_map" HAVE_UNORDERED_MAP)
check_include_file_cxx ("unordered_set" HAVE_UNORDERED_SET)
check_type_size ("unsigned __int16" HAVE___UINT16 LANGUAGE CXX)
check_type_size (mode_t HAVE_MODE_T LANGUAGE CXX) check_type_size (mode_t HAVE_MODE_T LANGUAGE CXX)
check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX) check_type_size (ssize_t HAVE_SSIZE_T LANGUAGE CXX)
check_type_size (u_int16_t HAVE_U_INT16_T LANGUAGE CXX)
check_type_size (uint16_t HAVE_UINT16_T LANGUAGE CXX)
check_function_exists (dladdr HAVE_DLADDR) check_function_exists (dladdr HAVE_DLADDR)
check_function_exists (fcntl HAVE_FCNTL) check_function_exists (fcntl HAVE_FCNTL)
@ -221,82 +208,8 @@ __declspec(selectany) int a;
int main(void) { return 0; } int main(void) { return 0; }
" HAVE___DECLSPEC) " HAVE___DECLSPEC)
check_cxx_source_compiles ("
#include <vector>
vector<int> t; int main() { }
" STL_NO_NAMESPACE)
check_cxx_source_compiles ("
#include <vector>
std::vector<int> t; int main() { }
" STL_STD_NAMESPACE)
check_cxx_source_compiles ("
#include <iostream>
std::ostream& operator<<(std::ostream&, struct s);
using ::operator<<;
int main() { }
" HAVE_USING_OPERATOR)
check_cxx_source_compiles ("
namespace Outer { namespace Inner { int i = 0; }}
using namespace Outer::Inner;;
int main() { return i; }
" HAVE_NAMESPACES)
check_cxx_source_compiles ("
__thread int tls;
int main() { }
" HAVE_GCC_TLS)
check_cxx_source_compiles ("
__declspec(thread) int tls;
int main() { }
" HAVE_MSVC_TLS)
check_cxx_source_compiles ("
thread_local int tls;
int main() { }
" HAVE_CXX11_TLS)
check_cxx_source_compiles ("
#include <type_traits>
std::aligned_storage<sizeof(char), alignof(char)>::type data;
int main() { }
" HAVE_ALIGNED_STORAGE)
check_cxx_source_compiles ("
#include <atomic>
std::atomic<int> i;
int main() { }
" HAVE_CXX11_ATOMIC)
check_cxx_source_compiles ("
constexpr int x = 0;
int main() { }
" HAVE_CXX11_CONSTEXPR)
check_cxx_source_compiles ("
#include <chrono>
std::chrono::seconds s;
int main() { }
" HAVE_CXX11_CHRONO)
check_cxx_source_compiles ("
#include <cstddef>
void foo(std::nullptr_t) {}
int main(void) { foo(nullptr); }
" HAVE_CXX11_NULLPTR_T)
if (WITH_TLS) if (WITH_TLS)
# Cygwin does not support the thread attribute. Don't bother. set (GLOG_THREAD_LOCAL_STORAGE 1)
if (HAVE_GCC_TLS)
set (GLOG_THREAD_LOCAL_STORAGE "__thread")
elseif (HAVE_MSVC_TLS)
set (GLOG_THREAD_LOCAL_STORAGE "__declspec(thread)")
elseif (HAVE_CXX11_TLS)
set (GLOG_THREAD_LOCAL_STORAGE thread_local)
endif (HAVE_GCC_TLS)
endif (WITH_TLS) endif (WITH_TLS)
set (_PC_FIELDS set (_PC_FIELDS
@ -345,59 +258,23 @@ int main(void)
endforeach (_PC_FIELD) endforeach (_PC_FIELD)
endif (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT) endif (HAVE_UCONTEXT_H AND NOT PC_FROM_UCONTEXT)
if (STL_STD_NAMESPACE)
set (STL_NAMESPACE std)
else (STL_STD_NAMESPACE)
set (STL_NAMESPACE "")
endif (STL_STD_NAMESPACE)
set (GOOGLE_NAMESPACE google) set (GOOGLE_NAMESPACE google)
set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {") set (_START_GOOGLE_NAMESPACE_ "namespace ${GOOGLE_NAMESPACE} {")
set (_END_GOOGLE_NAMESPACE_ "}") set (_END_GOOGLE_NAMESPACE_ "}")
set (ac_cv_have_glog_export 1) set (ac_cv_have_glog_export 1)
if (HAVE___UINT16)
set (ac_cv_have___uint16 1)
else (HAVE___UINT16)
set (ac_cv_have___uint16 0)
endif (HAVE___UINT16)
if (HAVE_INTTYPES_H)
set (ac_cv_have_inttypes_h 1)
else (HAVE_INTTYPES_H)
set (ac_cv_have_inttypes_h 0)
endif (HAVE_INTTYPES_H)
if (HAVE_LIB_GFLAGS) if (HAVE_LIB_GFLAGS)
set (ac_cv_have_libgflags 1) set (ac_cv_have_libgflags 1)
else (HAVE_LIB_GFLAGS) else (HAVE_LIB_GFLAGS)
set (ac_cv_have_libgflags 0) set (ac_cv_have_libgflags 0)
endif (HAVE_LIB_GFLAGS) endif (HAVE_LIB_GFLAGS)
if (HAVE_STDINT_H)
set (ac_cv_have_stdint_h 1)
else (HAVE_STDINT_H)
set (ac_cv_have_stdint_h 0)
endif (HAVE_STDINT_H)
if (HAVE_SYS_TYPES_H) if (HAVE_SYS_TYPES_H)
set (ac_cv_have_systypes_h 1) set (ac_cv_have_systypes_h 1)
else (HAVE_SYS_TYPES_H) else (HAVE_SYS_TYPES_H)
set (ac_cv_have_systypes_h 0) set (ac_cv_have_systypes_h 0)
endif (HAVE_SYS_TYPES_H) endif (HAVE_SYS_TYPES_H)
if (HAVE_U_INT16_T)
set (ac_cv_have_u_int16_t 1)
else (HAVE_U_INT16_T)
set (ac_cv_have_u_int16_t 0)
endif (HAVE_U_INT16_T)
if (HAVE_UINT16_T)
set (ac_cv_have_uint16_t 1)
else (HAVE_UINT16_T)
set (ac_cv_have_uint16_t 0)
endif (HAVE_UINT16_T)
if (HAVE_SSIZE_T) if (HAVE_SSIZE_T)
set (ac_cv_have_ssize_t 1) set (ac_cv_have_ssize_t 1)
else (HAVE_SSIZE_T) else (HAVE_SSIZE_T)
@ -421,11 +298,9 @@ set (ac_google_end_namespace ${_END_GOOGLE_NAMESPACE_})
set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_}) set (ac_google_start_namespace ${_START_GOOGLE_NAMESPACE_})
if (HAVE___ATTRIBUTE__) if (HAVE___ATTRIBUTE__)
set (ac_cv___attribute___noreturn "__attribute__((noreturn))")
set (ac_cv___attribute___noinline "__attribute__((noinline))") set (ac_cv___attribute___noinline "__attribute__((noinline))")
set (ac_cv___attribute___printf_4_5 "__attribute__((__format__(__printf__, 4, 5)))") set (ac_cv___attribute___printf_4_5 "__attribute__((__format__(__printf__, 4, 5)))")
elseif (HAVE___DECLSPEC) elseif (HAVE___DECLSPEC)
set (ac_cv___attribute___noreturn "__declspec(noreturn)")
#set (ac_cv___attribute___noinline "__declspec(noinline)") #set (ac_cv___attribute___noinline "__declspec(noinline)")
endif (HAVE___ATTRIBUTE__) endif (HAVE___ATTRIBUTE__)
@ -435,40 +310,10 @@ else (HAVE___BUILTIN_EXPECT)
set (ac_cv_have___builtin_expect 0) set (ac_cv_have___builtin_expect 0)
endif (HAVE___BUILTIN_EXPECT) endif (HAVE___BUILTIN_EXPECT)
if (HAVE_USING_OPERATOR)
set (ac_cv_cxx_using_operator 1)
else (HAVE_USING_OPERATOR)
set (ac_cv_cxx_using_operator 0)
endif (HAVE_USING_OPERATOR)
if (HAVE_CXX11_CONSTEXPR)
set (ac_cv_cxx11_constexpr 1)
else (HAVE_CXX11_CONSTEXPR)
set (ac_cv_cxx11_constexpr 0)
endif (HAVE_CXX11_CONSTEXPR)
if (HAVE_CXX11_CHRONO)
set (ac_cv_cxx11_chrono 1)
else (HAVE_CXX11_CHRONO)
set (ac_cv_cxx11_chrono 0)
endif (HAVE_CXX11_CHRONO)
if (HAVE_CXX11_NULLPTR_T)
set (ac_cv_cxx11_nullptr_t 1)
else (HAVE_CXX11_NULLPTR_T)
set (ac_cv_cxx11_nullptr_t 0)
endif (HAVE_CXX11_NULLPTR_T)
if (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS) if (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
set (HAVE_STACKTRACE 1) set (HAVE_STACKTRACE 1)
endif (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS) endif (HAVE_EXECINFO_BACKTRACE AND HAVE_EXECINFO_BACKTRACE_SYMBOLS)
if (HAVE_CXX11_ATOMIC)
set (ac_cv_cxx11_atomic 1)
else (HAVE_CXX11_ATOMIC)
set (ac_cv_cxx11_atomic 0)
endif (HAVE_CXX11_ATOMIC)
if (WITH_SYMBOLIZE) if (WITH_SYMBOLIZE)
if (WIN32 OR CYGWIN) if (WIN32 OR CYGWIN)
cmake_push_check_state (RESET) cmake_push_check_state (RESET)
@ -645,10 +490,12 @@ add_library (glog_internal OBJECT
${_glog_BINARY_CMake_MODULES} ${_glog_BINARY_CMake_MODULES}
${GLOG_SRCS} ${GLOG_SRCS}
) )
target_compile_features (glog_internal PUBLIC $<TARGET_PROPERTY:glog,COMPILE_FEATURES>)
add_library (glog add_library (glog
$<TARGET_OBJECTS:glog_internal> $<TARGET_OBJECTS:glog_internal>
) )
target_compile_features (glog PUBLIC cxx_std_14)
add_library (glog::glog ALIAS glog) add_library (glog::glog ALIAS glog)
@ -806,21 +653,6 @@ if (BUILD_TESTING)
-Wno-deprecated) -Wno-deprecated)
endif (HAVE_NO_DEPRECATED) endif (HAVE_NO_DEPRECATED)
if (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
target_compile_definitions (stl_logging_unittest PRIVATE
GLOG_STL_LOGGING_FOR_UNORDERED)
endif (HAVE_UNORDERED_MAP AND HAVE_UNORDERED_SET)
if (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
target_compile_definitions (stl_logging_unittest PRIVATE
GLOG_STL_LOGGING_FOR_TR1_UNORDERED)
endif (HAVE_TR1_UNORDERED_MAP AND HAVE_TR1_UNORDERED_SET)
if (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
target_compile_definitions (stl_logging_unittest PRIVATE
GLOG_STL_LOGGING_FOR_EXT_HASH)
endif (HAVE_EXT_HASH_MAP AND HAVE_EXT_HASH_SET)
if (HAVE_EXT_SLIST) if (HAVE_EXT_SLIST)
target_compile_definitions (stl_logging_unittest PRIVATE target_compile_definitions (stl_logging_unittest PRIVATE
GLOG_STL_LOGGING_FOR_EXT_SLIST) GLOG_STL_LOGGING_FOR_EXT_SLIST)

View File

@ -3,7 +3,7 @@ Google Logging Library
|Linux Github actions| |Windows Github actions| |macOS Github actions| |Codecov| |Linux Github actions| |Windows Github actions| |macOS Github actions| |Codecov|
Google Logging (glog) is a C++98 library that implements application-level Google Logging (glog) is a C++14 library that implements application-level
logging. The library provides logging APIs based on C++-style streams and logging. The library provides logging APIs based on C++-style streams and
various helper macros. various helper macros.
@ -430,12 +430,12 @@ for example:
CHECK_EQ(string("abc")[1], b); CHECK_EQ(string("abc")[1], b);
The compiler reports an error if one of the arguments is a pointer and the other The compiler reports an error if one of the arguments is a pointer and the other
is :cpp:`NULL`. To work around this, simply :cpp:`static_cast` :cpp:`NULL` to is :cpp:`nullptr`. To work around this, simply :cpp:`static_cast` :cpp:`nullptr` to
the type of the desired pointer. the type of the desired pointer.
.. code:: cpp .. code:: cpp
CHECK_EQ(some_ptr, static_cast<SomeType*>(NULL)); CHECK_EQ(some_ptr, static_cast<SomeType*>(nullptr));
Better yet, use the ``CHECK_NOTNULL`` macro: Better yet, use the ``CHECK_NOTNULL`` macro:
@ -461,8 +461,8 @@ aborting the application.
If you are comparing C strings (:cpp:`char *`), a handy set of macros performs If you are comparing C strings (:cpp:`char *`), a handy set of macros performs
case sensitive as well as case insensitive comparisons - ``CHECK_STREQ``, case sensitive as well as case insensitive comparisons - ``CHECK_STREQ``,
``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The CASE versions ``CHECK_STRNE``, ``CHECK_STRCASEEQ``, and ``CHECK_STRCASENE``. The CASE versions
are case-insensitive. You can safely pass :cpp:`NULL` pointers for this macro. They are case-insensitive. You can safely pass :cpp:`nullptr` pointers for this macro. They
treat :cpp:`NULL` and any non-:cpp:`NULL` string as not equal. Two :cpp:`NULL`\ treat :cpp:`nullptr` and any non-:cpp:`nullptr` string as not equal. Two :cpp:`nullptr`\
s are equal. s are equal.
Note that both arguments may be temporary strings which are destructed Note that both arguments may be temporary strings which are destructed
@ -563,7 +563,7 @@ For example:
/* This function writes a prefix that matches glog's default format. /* This function writes a prefix that matches glog's default format.
* (The third parameter can be used to receive user-supplied data, and is * (The third parameter can be used to receive user-supplied data, and is
* NULL by default.) * nullptr by default.)
*/ */
void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) { void CustomPrefix(std::ostream &s, const LogMessageInfo &l, void*) {
s << l.severity[0] s << l.severity[0]
@ -668,13 +668,13 @@ description of the current state of errno to their output lines. E.g.
.. code:: cpp .. code:: cpp
PCHECK(write(1, NULL, 2) >= 0) << "Write NULL failed"; PCHECK(write(1, nullptr, 2) >= 0) << "Write nullptr failed";
This check fails with the following error message. This check fails with the following error message.
:: ::
F0825 185142 test.cc:22] Check failed: write(1, NULL, 2) >= 0 Write NULL failed: Bad address [14] F0825 185142 test.cc:22] Check failed: write(1, nullptr, 2) >= 0 Write nullptr failed: Bad address [14]
Syslog Syslog
~~~~~~ ~~~~~~

View File

@ -53,11 +53,10 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
) )
common_copts = [ common_copts = [
"-std=c++14",
"-DGLOG_BAZEL_BUILD", "-DGLOG_BAZEL_BUILD",
# Inject a C++ namespace. # Inject a C++ namespace.
"-DGOOGLE_NAMESPACE='%s'" % namespace, "-DGOOGLE_NAMESPACE='%s'" % namespace,
"-DHAVE_CXX11_NULLPTR_T",
"-DHAVE_STDINT_H",
"-DHAVE_STRING_H", "-DHAVE_STRING_H",
"-I%s/glog_internal" % gendir, "-I%s/glog_internal" % gendir,
] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else []) ] + (["-DHAVE_LIB_GFLAGS"] if with_gflags else [])
@ -260,12 +259,6 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
) )
common_config = { common_config = {
"@ac_cv_cxx11_atomic@": "1",
"@ac_cv_cxx11_constexpr@": "1",
"@ac_cv_cxx11_chrono@": "1",
"@ac_cv_cxx11_nullptr_t@": "1",
"@ac_cv_cxx_using_operator@": "1",
"@ac_cv_have_inttypes_h@": "0",
"@ac_cv_have_u_int16_t@": "0", "@ac_cv_have_u_int16_t@": "0",
"@ac_cv_have_glog_export@": "0", "@ac_cv_have_glog_export@": "0",
"@ac_google_start_namespace@": "namespace google {", "@ac_google_start_namespace@": "namespace google {",
@ -275,31 +268,23 @@ def glog_library(namespace = "google", with_gflags = 1, **kwargs):
posix_config = dict_union(common_config, { posix_config = dict_union(common_config, {
"@ac_cv___attribute___noinline@": "__attribute__((noinline))", "@ac_cv___attribute___noinline@": "__attribute__((noinline))",
"@ac_cv___attribute___noreturn@": "__attribute__((noreturn))",
"@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))", "@ac_cv___attribute___printf_4_5@": "__attribute__((__format__(__printf__, 4, 5)))",
"@ac_cv_have___builtin_expect@": "1", "@ac_cv_have___builtin_expect@": "1",
"@ac_cv_have___uint16@": "0",
"@ac_cv_have_libgflags@": "1" if with_gflags else "0", "@ac_cv_have_libgflags@": "1" if with_gflags else "0",
"@ac_cv_have_mode_t@": "1", "@ac_cv_have_mode_t@": "1",
"@ac_cv_have_ssize_t@": "1", "@ac_cv_have_ssize_t@": "1",
"@ac_cv_have_stdint_h@": "1",
"@ac_cv_have_systypes_h@": "1", "@ac_cv_have_systypes_h@": "1",
"@ac_cv_have_uint16_t@": "1",
"@ac_cv_have_unistd_h@": "1", "@ac_cv_have_unistd_h@": "1",
}) })
windows_config = dict_union(common_config, { windows_config = dict_union(common_config, {
"@ac_cv___attribute___noinline@": "", "@ac_cv___attribute___noinline@": "",
"@ac_cv___attribute___noreturn@": "__declspec(noreturn)",
"@ac_cv___attribute___printf_4_5@": "", "@ac_cv___attribute___printf_4_5@": "",
"@ac_cv_have___builtin_expect@": "0", "@ac_cv_have___builtin_expect@": "0",
"@ac_cv_have___uint16@": "1",
"@ac_cv_have_libgflags@": "0", "@ac_cv_have_libgflags@": "0",
"@ac_cv_have_mode_t@": "0", "@ac_cv_have_mode_t@": "0",
"@ac_cv_have_ssize_t@": "0", "@ac_cv_have_ssize_t@": "0",
"@ac_cv_have_stdint_h@": "0",
"@ac_cv_have_systypes_h@": "0", "@ac_cv_have_systypes_h@": "0",
"@ac_cv_have_uint16_t@": "0",
"@ac_cv_have_unistd_h@": "0", "@ac_cv_have_unistd_h@": "0",
}) })

View File

@ -135,13 +135,14 @@
#define EnvToString(envname, dflt) \ #define EnvToString(envname, dflt) \
(!getenv(envname) ? (dflt) : getenv(envname)) (!getenv(envname) ? (dflt) : getenv(envname))
#define EnvToBool(envname, dflt) \ #define EnvToBool(envname, dflt) \
(!getenv(envname) ? (dflt) : memchr("tTyY1\0", getenv(envname)[0], 6) != NULL) (!getenv(envname) ? (dflt) \
: memchr("tTyY1\0", getenv(envname)[0], 6) != nullptr)
#define EnvToInt(envname, dflt) \ #define EnvToInt(envname, dflt) \
(!getenv(envname) ? (dflt) : strtol(getenv(envname), NULL, 10)) (!getenv(envname) ? (dflt) : strtol(getenv(envname), nullptr, 10))
#define EnvToUInt(envname, dflt) \ #define EnvToUInt(envname, dflt) \
(!getenv(envname) ? (dflt) : strtoul(getenv(envname), NULL, 10)) (!getenv(envname) ? (dflt) : strtoul(getenv(envname), nullptr, 10))
#endif // BASE_COMMANDLINEFLAGS_H__ #endif // BASE_COMMANDLINEFLAGS_H__

View File

@ -35,7 +35,7 @@
class GoogleInitializer { class GoogleInitializer {
public: public:
typedef void (*void_function)(void); using void_function = void (*)();
GoogleInitializer(const char*, void_function f) { GoogleInitializer(const char*, void_function f) {
f(); f();
} }

View File

@ -139,7 +139,7 @@
# endif # endif
# endif # endif
# include <pthread.h> # include <pthread.h>
typedef pthread_rwlock_t MutexType; using MutexType = pthread_rwlock_t;
#elif defined(HAVE_PTHREAD) #elif defined(HAVE_PTHREAD)
# include <pthread.h> # include <pthread.h>
typedef pthread_mutex_t MutexType; typedef pthread_mutex_t MutexType;
@ -194,10 +194,10 @@ class Mutex {
inline void SetIsSafe() { is_safe_ = true; } inline void SetIsSafe() { is_safe_ = true; }
// Catch the error of writing Mutex when intending MutexLock. // Catch the error of writing Mutex when intending MutexLock.
Mutex(Mutex* /*ignored*/) {} explicit Mutex(Mutex * /*ignored*/) {}
// Disallow "evil" constructors // Disallow "evil" constructors
Mutex(const Mutex&); Mutex(const Mutex &) = delete;
void operator=(const Mutex&); void operator=(const Mutex &) = delete;
}; };
// Now the implementation of Mutex for various systems // Now the implementation of Mutex for various systems
@ -244,7 +244,7 @@ void Mutex::ReaderUnlock() { Unlock(); }
Mutex::Mutex() { Mutex::Mutex() {
SetIsSafe(); SetIsSafe();
if (is_safe_ && pthread_rwlock_init(&mutex_, NULL) != 0) abort(); if (is_safe_ && pthread_rwlock_init(&mutex_, nullptr) != 0) abort();
} }
Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); } Mutex::~Mutex() { SAFE_PTHREAD(pthread_rwlock_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); } void Mutex::Lock() { SAFE_PTHREAD(pthread_rwlock_wrlock); }
@ -266,7 +266,7 @@ void Mutex::ReaderUnlock() { SAFE_PTHREAD(pthread_rwlock_unlock); }
Mutex::Mutex() { Mutex::Mutex() {
SetIsSafe(); SetIsSafe();
if (is_safe_ && pthread_mutex_init(&mutex_, NULL) != 0) abort(); if (is_safe_ && pthread_mutex_init(&mutex_, nullptr) != 0) abort();
} }
Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); } Mutex::~Mutex() { SAFE_PTHREAD(pthread_mutex_destroy); }
void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); } void Mutex::Lock() { SAFE_PTHREAD(pthread_mutex_lock); }
@ -292,8 +292,8 @@ class MutexLock {
private: private:
Mutex * const mu_; Mutex * const mu_;
// Disallow "evil" constructors // Disallow "evil" constructors
MutexLock(const MutexLock&); MutexLock(const MutexLock &) = delete;
void operator=(const MutexLock&); void operator=(const MutexLock &) = delete;
}; };
// ReaderMutexLock and WriterMutexLock do the same, for rwlocks // ReaderMutexLock and WriterMutexLock do the same, for rwlocks
@ -304,8 +304,8 @@ class ReaderMutexLock {
private: private:
Mutex * const mu_; Mutex * const mu_;
// Disallow "evil" constructors // Disallow "evil" constructors
ReaderMutexLock(const ReaderMutexLock&); ReaderMutexLock(const ReaderMutexLock &) = delete;
void operator=(const ReaderMutexLock&); void operator=(const ReaderMutexLock &) = delete;
}; };
class WriterMutexLock { class WriterMutexLock {
@ -315,8 +315,8 @@ class WriterMutexLock {
private: private:
Mutex * const mu_; Mutex * const mu_;
// Disallow "evil" constructors // Disallow "evil" constructors
WriterMutexLock(const WriterMutexLock&); WriterMutexLock(const WriterMutexLock &) = delete;
void operator=(const WriterMutexLock&); void operator=(const WriterMutexLock &) = delete;
}; };
// Catch bug where variable name is omitted, e.g. MutexLock (&mu); // Catch bug where variable name is omitted, e.g. MutexLock (&mu);

View File

@ -74,7 +74,7 @@ int main(int argc, char **argv) {
#endif #endif
// Make sure stderr is not buffered as stderr seems to be buffered // Make sure stderr is not buffered as stderr seems to be buffered
// on recent windows. // on recent windows.
setbuf(stderr, NULL); setbuf(stderr, nullptr);
// Test some basics before InitGoogleLogging: // Test some basics before InitGoogleLogging:
CaptureTestStderr(); CaptureTestStderr();

View File

@ -79,7 +79,7 @@ int main(int argc, char **argv) {
#endif #endif
// Make sure stderr is not buffered as stderr seems to be buffered // Make sure stderr is not buffered as stderr seems to be buffered
// on recent windows. // on recent windows.
setbuf(stderr, NULL); setbuf(stderr, nullptr);
// Test some basics before InitGoogleLogging: // Test some basics before InitGoogleLogging:
CaptureTestStderr(); CaptureTestStderr();

View File

@ -75,7 +75,7 @@ int main(int argc, char **argv) {
#endif #endif
// Make sure stderr is not buffered as stderr seems to be buffered // Make sure stderr is not buffered as stderr seems to be buffered
// on recent windows. // on recent windows.
setbuf(stderr, NULL); setbuf(stderr, nullptr);
// Test some basics before InitGoogleLogging: // Test some basics before InitGoogleLogging:
CaptureTestStderr(); CaptureTestStderr();

View File

@ -1,9 +1,6 @@
#ifndef GLOG_CONFIG_H #ifndef GLOG_CONFIG_H
#define GLOG_CONFIG_H #define GLOG_CONFIG_H
/* define if glog doesn't use RTTI */
#cmakedefine DISABLE_RTTI
/* Namespace for Google classes */ /* Namespace for Google classes */
#cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE} #cmakedefine GOOGLE_NAMESPACE ${GOOGLE_NAMESPACE}
@ -28,9 +25,6 @@
/* Define to 1 if you have the <glob.h> header file. */ /* Define to 1 if you have the <glob.h> header file. */
#cmakedefine HAVE_GLOB_H #cmakedefine HAVE_GLOB_H
/* Define to 1 if you have the <inttypes.h> header file. */
#cmakedefine HAVE_INTTYPES_H ${HAVE_INTTYPES_H}
/* Define to 1 if you have the `pthread' library (-lpthread). */ /* Define to 1 if you have the `pthread' library (-lpthread). */
#cmakedefine HAVE_LIBPTHREAD #cmakedefine HAVE_LIBPTHREAD
@ -55,9 +49,6 @@
/* define to disable multithreading support. */ /* define to disable multithreading support. */
#cmakedefine NO_THREADS #cmakedefine NO_THREADS
/* define if the compiler implements namespaces */
#cmakedefine HAVE_NAMESPACES
/* Define if you have the 'pread' function */ /* Define if you have the 'pread' function */
#cmakedefine HAVE_PREAD #cmakedefine HAVE_PREAD
@ -79,9 +70,6 @@
/* Define if you have the `sigaltstack' function */ /* Define if you have the `sigaltstack' function */
#cmakedefine HAVE_SIGALTSTACK #cmakedefine HAVE_SIGALTSTACK
/* Define to 1 if you have the <stdint.h> header file. */
#cmakedefine HAVE_STDINT_H ${HAVE_STDINT_H}
/* Define to 1 if you have the <strings.h> header file. */ /* Define to 1 if you have the <strings.h> header file. */
#cmakedefine HAVE_STRINGS_H #cmakedefine HAVE_STRINGS_H
@ -124,9 +112,6 @@
/* Define if you linking to _Unwind_GetIP is possible. */ /* Define if you linking to _Unwind_GetIP is possible. */
#cmakedefine HAVE__UNWIND_GETIP #cmakedefine HAVE__UNWIND_GETIP
/* define if the compiler supports using expression for operator */
#cmakedefine HAVE_USING_OPERATOR
/* define if your compiler has __attribute__ */ /* define if your compiler has __attribute__ */
#cmakedefine HAVE___ATTRIBUTE__ #cmakedefine HAVE___ATTRIBUTE__
@ -149,27 +134,6 @@
*/ */
#cmakedefine LT_OBJDIR #cmakedefine LT_OBJDIR
/* Name of package */
#cmakedefine PACKAGE
/* Define to the address where bug reports for this package should be sent. */
#cmakedefine PACKAGE_BUGREPORT
/* Define to the full name of this package. */
#cmakedefine PACKAGE_NAME
/* Define to the full name and version of this package. */
#cmakedefine PACKAGE_STRING
/* Define to the one symbol short name of this package. */
#cmakedefine PACKAGE_TARNAME
/* Define to the home page for this package. */
#cmakedefine PACKAGE_URL
/* Define to the version of this package. */
#cmakedefine PACKAGE_VERSION
/* How to access the PC from a struct ucontext */ /* How to access the PC from a struct ucontext */
#cmakedefine PC_FROM_UCONTEXT #cmakedefine PC_FROM_UCONTEXT
@ -183,29 +147,11 @@
/* The size of `void *', as computed by sizeof. */ /* The size of `void *', as computed by sizeof. */
#cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P} #cmakedefine SIZEOF_VOID_P ${SIZEOF_VOID_P}
/* the namespace where STL code like vector<> is defined */
#cmakedefine STL_NAMESPACE ${STL_NAMESPACE}
/* location of source code */ /* location of source code */
#cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR} #cmakedefine TEST_SRC_DIR ${TEST_SRC_DIR}
/* Define to necessary thread-local storage attribute. */ /* Define if thread-local storage is enabled. */
#cmakedefine GLOG_THREAD_LOCAL_STORAGE ${GLOG_THREAD_LOCAL_STORAGE} #cmakedefine GLOG_THREAD_LOCAL_STORAGE
/* Check whether aligned_storage and alignof present */
#cmakedefine HAVE_ALIGNED_STORAGE ${HAVE_ALIGNED_STORAGE}
/* Check whether C++11 atomic is available */
#cmakedefine HAVE_CXX11_ATOMIC ${HAVE_CXX11_ATOMIC}
/* Check whether C++11 chrono is available */
#cmakedefine HAVE_CXX11_CHRONO ${HAVE_CXX11_CHRONO}
/* Check whether C++11 nullptr_t is available */
#cmakedefine HAVE_CXX11_NULLPTR_T ${HAVE_CXX11_NULLPTR_T}
/* Version number of package */
#cmakedefine VERSION
#ifdef GLOG_BAZEL_BUILD #ifdef GLOG_BAZEL_BUILD

View File

@ -34,9 +34,10 @@
// //
// Note that we only have partial C++0x support yet. // Note that we only have partial C++0x support yet.
#include <cstdio> // for NULL
#include "demangle.h" #include "demangle.h"
#include <cstdio> // for nullptr
#include "utilities.h" #include "utilities.h"
#if defined(GLOG_OS_WINDOWS) #if defined(GLOG_OS_WINDOWS)
@ -53,99 +54,49 @@ struct AbbrevPair {
// List of operators from Itanium C++ ABI. // List of operators from Itanium C++ ABI.
static const AbbrevPair kOperatorList[] = { static const AbbrevPair kOperatorList[] = {
{ "nw", "new" }, {"nw", "new"}, {"na", "new[]"}, {"dl", "delete"}, {"da", "delete[]"},
{ "na", "new[]" }, {"ps", "+"}, {"ng", "-"}, {"ad", "&"}, {"de", "*"},
{ "dl", "delete" }, {"co", "~"}, {"pl", "+"}, {"mi", "-"}, {"ml", "*"},
{ "da", "delete[]" }, {"dv", "/"}, {"rm", "%"}, {"an", "&"}, {"or", "|"},
{ "ps", "+" }, {"eo", "^"}, {"aS", "="}, {"pL", "+="}, {"mI", "-="},
{ "ng", "-" }, {"mL", "*="}, {"dV", "/="}, {"rM", "%="}, {"aN", "&="},
{ "ad", "&" }, {"oR", "|="}, {"eO", "^="}, {"ls", "<<"}, {"rs", ">>"},
{ "de", "*" }, {"lS", "<<="}, {"rS", ">>="}, {"eq", "=="}, {"ne", "!="},
{ "co", "~" }, {"lt", "<"}, {"gt", ">"}, {"le", "<="}, {"ge", ">="},
{ "pl", "+" }, {"nt", "!"}, {"aa", "&&"}, {"oo", "||"}, {"pp", "++"},
{ "mi", "-" }, {"mm", "--"}, {"cm", ","}, {"pm", "->*"}, {"pt", "->"},
{ "ml", "*" }, {"cl", "()"}, {"ix", "[]"}, {"qu", "?"}, {"st", "sizeof"},
{ "dv", "/" }, {"sz", "sizeof"}, {nullptr, nullptr},
{ "rm", "%" },
{ "an", "&" },
{ "or", "|" },
{ "eo", "^" },
{ "aS", "=" },
{ "pL", "+=" },
{ "mI", "-=" },
{ "mL", "*=" },
{ "dV", "/=" },
{ "rM", "%=" },
{ "aN", "&=" },
{ "oR", "|=" },
{ "eO", "^=" },
{ "ls", "<<" },
{ "rs", ">>" },
{ "lS", "<<=" },
{ "rS", ">>=" },
{ "eq", "==" },
{ "ne", "!=" },
{ "lt", "<" },
{ "gt", ">" },
{ "le", "<=" },
{ "ge", ">=" },
{ "nt", "!" },
{ "aa", "&&" },
{ "oo", "||" },
{ "pp", "++" },
{ "mm", "--" },
{ "cm", "," },
{ "pm", "->*" },
{ "pt", "->" },
{ "cl", "()" },
{ "ix", "[]" },
{ "qu", "?" },
{ "st", "sizeof" },
{ "sz", "sizeof" },
{ NULL, NULL },
}; };
// List of builtin types from Itanium C++ ABI. // List of builtin types from Itanium C++ ABI.
static const AbbrevPair kBuiltinTypeList[] = { static const AbbrevPair kBuiltinTypeList[] = {
{ "v", "void" }, {"v", "void"}, {"w", "wchar_t"},
{ "w", "wchar_t" }, {"b", "bool"}, {"c", "char"},
{ "b", "bool" }, {"a", "signed char"}, {"h", "unsigned char"},
{ "c", "char" }, {"s", "short"}, {"t", "unsigned short"},
{ "a", "signed char" }, {"i", "int"}, {"j", "unsigned int"},
{ "h", "unsigned char" }, {"l", "long"}, {"m", "unsigned long"},
{ "s", "short" }, {"x", "long long"}, {"y", "unsigned long long"},
{ "t", "unsigned short" }, {"n", "__int128"}, {"o", "unsigned __int128"},
{ "i", "int" }, {"f", "float"}, {"d", "double"},
{ "j", "unsigned int" }, {"e", "long double"}, {"g", "__float128"},
{ "l", "long" }, {"z", "ellipsis"}, {nullptr, nullptr}};
{ "m", "unsigned long" },
{ "x", "long long" },
{ "y", "unsigned long long" },
{ "n", "__int128" },
{ "o", "unsigned __int128" },
{ "f", "float" },
{ "d", "double" },
{ "e", "long double" },
{ "g", "__float128" },
{ "z", "ellipsis" },
{ NULL, NULL }
};
// List of substitutions Itanium C++ ABI. // List of substitutions Itanium C++ ABI.
static const AbbrevPair kSubstitutionList[] = { static const AbbrevPair kSubstitutionList[] = {
{ "St", "" }, {"St", ""},
{ "Sa", "allocator" }, {"Sa", "allocator"},
{ "Sb", "basic_string" }, {"Sb", "basic_string"},
// std::basic_string<char, std::char_traits<char>,std::allocator<char> > // std::basic_string<char, std::char_traits<char>,std::allocator<char> >
{ "Ss", "string"}, {"Ss", "string"},
// std::basic_istream<char, std::char_traits<char> > // std::basic_istream<char, std::char_traits<char> >
{ "Si", "istream" }, {"Si", "istream"},
// std::basic_ostream<char, std::char_traits<char> > // std::basic_ostream<char, std::char_traits<char> >
{ "So", "ostream" }, {"So", "ostream"},
// std::basic_iostream<char, std::char_traits<char> > // std::basic_iostream<char, std::char_traits<char> >
{ "Sd", "iostream" }, {"Sd", "iostream"},
{ NULL, NULL } {nullptr, nullptr}};
};
// State needed for demangling. // State needed for demangling.
struct State { struct State {
@ -197,7 +148,7 @@ static void InitState(State *state, const char *mangled,
state->out_cur = out; state->out_cur = out;
state->out_begin = out; state->out_begin = out;
state->out_end = out + out_size; state->out_end = out + out_size;
state->prev_name = NULL; state->prev_name = nullptr;
state->prev_name_length = -1; state->prev_name_length = -1;
state->nest_level = -1; state->nest_level = -1;
state->append = true; state->append = true;
@ -246,7 +197,7 @@ static bool Optional(bool) {
} }
// This function is used for handling <non-terminal>+ syntax. // This function is used for handling <non-terminal>+ syntax.
typedef bool (*ParseFunc)(State *); using ParseFunc = bool (*)(State *);
static bool OneOrMore(ParseFunc parse_func, State *state) { static bool OneOrMore(ParseFunc parse_func, State *state) {
if (parse_func(state)) { if (parse_func(state)) {
while (parse_func(state)) { while (parse_func(state)) {
@ -650,7 +601,7 @@ static bool ParseNumber(State *state, int *number_out) {
} }
if (p != state->mangled_cur) { // Conversion succeeded. if (p != state->mangled_cur) { // Conversion succeeded.
state->mangled_cur = p; state->mangled_cur = p;
if (number_out != NULL) { if (number_out != nullptr) {
*number_out = number * sign; *number_out = number * sign;
} }
return true; return true;
@ -755,7 +706,7 @@ static bool ParseOperatorName(State *state) {
} }
// We may want to perform a binary search if we really need speed. // We may want to perform a binary search if we really need speed.
const AbbrevPair *p; const AbbrevPair *p;
for (p = kOperatorList; p->abbrev != NULL; ++p) { for (p = kOperatorList; p->abbrev != nullptr; ++p) {
if (state->mangled_cur[0] == p->abbrev[0] && if (state->mangled_cur[0] == p->abbrev[0] &&
state->mangled_cur[1] == p->abbrev[1]) { state->mangled_cur[1] == p->abbrev[1]) {
MaybeAppend(state, "operator"); MaybeAppend(state, "operator");
@ -817,9 +768,8 @@ static bool ParseSpecialName(State *state) {
// G++ extensions // G++ extensions
if (ParseTwoCharToken(state, "TC") && ParseType(state) && if (ParseTwoCharToken(state, "TC") && ParseType(state) &&
ParseNumber(state, NULL) && ParseOneCharToken(state, '_') && ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
DisableAppend(state) && DisableAppend(state) && ParseType(state)) {
ParseType(state)) {
RestoreAppend(state, copy.append); RestoreAppend(state, copy.append);
return true; return true;
} }
@ -869,15 +819,13 @@ static bool ParseCallOffset(State *state) {
} }
// <nv-offset> ::= <(offset) number> // <nv-offset> ::= <(offset) number>
static bool ParseNVOffset(State *state) { static bool ParseNVOffset(State *state) { return ParseNumber(state, nullptr); }
return ParseNumber(state, NULL);
}
// <v-offset> ::= <(offset) number> _ <(virtual offset) number> // <v-offset> ::= <(offset) number> _ <(virtual offset) number>
static bool ParseVOffset(State *state) { static bool ParseVOffset(State *state) {
State copy = *state; State copy = *state;
if (ParseNumber(state, NULL) && ParseOneCharToken(state, '_') && if (ParseNumber(state, nullptr) && ParseOneCharToken(state, '_') &&
ParseNumber(state, NULL)) { ParseNumber(state, nullptr)) {
return true; return true;
} }
*state = copy; *state = copy;
@ -997,7 +945,7 @@ static bool ParseCVQualifiers(State *state) {
// ::= u <source-name> // ::= u <source-name>
static bool ParseBuiltinType(State *state) { static bool ParseBuiltinType(State *state) {
const AbbrevPair *p; const AbbrevPair *p;
for (p = kBuiltinTypeList; p->abbrev != NULL; ++p) { for (p = kBuiltinTypeList; p->abbrev != nullptr; ++p) {
if (state->mangled_cur[0] == p->abbrev[0]) { if (state->mangled_cur[0] == p->abbrev[0]) {
MaybeAppend(state, p->real_name); MaybeAppend(state, p->real_name);
++state->mangled_cur; ++state->mangled_cur;
@ -1047,7 +995,7 @@ static bool ParseClassEnumType(State *state) {
// ::= A [<(dimension) expression>] _ <(element) type> // ::= A [<(dimension) expression>] _ <(element) type>
static bool ParseArrayType(State *state) { static bool ParseArrayType(State *state) {
State copy = *state; State copy = *state;
if (ParseOneCharToken(state, 'A') && ParseNumber(state, NULL) && if (ParseOneCharToken(state, 'A') && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_') && ParseType(state)) { ParseOneCharToken(state, '_') && ParseType(state)) {
return true; return true;
} }
@ -1081,7 +1029,7 @@ static bool ParseTemplateParam(State *state) {
} }
State copy = *state; State copy = *state;
if (ParseOneCharToken(state, 'T') && ParseNumber(state, NULL) && if (ParseOneCharToken(state, 'T') && ParseNumber(state, nullptr) &&
ParseOneCharToken(state, '_')) { ParseOneCharToken(state, '_')) {
MaybeAppend(state, "?"); // We don't support template substitutions. MaybeAppend(state, "?"); // We don't support template substitutions.
return true; return true;
@ -1205,8 +1153,7 @@ static bool ParseExpression(State *state) {
static bool ParseExprPrimary(State *state) { static bool ParseExprPrimary(State *state) {
State copy = *state; State copy = *state;
if (ParseOneCharToken(state, 'L') && ParseType(state) && if (ParseOneCharToken(state, 'L') && ParseType(state) &&
ParseNumber(state, NULL) && ParseNumber(state, nullptr) && ParseOneCharToken(state, 'E')) {
ParseOneCharToken(state, 'E')) {
return true; return true;
} }
*state = copy; *state = copy;
@ -1256,7 +1203,7 @@ static bool ParseLocalName(State *state) {
// <discriminator> := _ <(non-negative) number> // <discriminator> := _ <(non-negative) number>
static bool ParseDiscriminator(State *state) { static bool ParseDiscriminator(State *state) {
State copy = *state; State copy = *state;
if (ParseOneCharToken(state, '_') && ParseNumber(state, NULL)) { if (ParseOneCharToken(state, '_') && ParseNumber(state, nullptr)) {
return true; return true;
} }
*state = copy; *state = copy;
@ -1283,7 +1230,7 @@ static bool ParseSubstitution(State *state) {
// Expand abbreviations like "St" => "std". // Expand abbreviations like "St" => "std".
if (ParseOneCharToken(state, 'S')) { if (ParseOneCharToken(state, 'S')) {
const AbbrevPair *p; const AbbrevPair *p;
for (p = kSubstitutionList; p->abbrev != NULL; ++p) { for (p = kSubstitutionList; p->abbrev != nullptr; ++p) {
if (state->mangled_cur[0] == p->abbrev[1]) { if (state->mangled_cur[0] == p->abbrev[1]) {
MaybeAppend(state, "std"); MaybeAppend(state, "std");
if (p->real_name[0] != '\0') { if (p->real_name[0] != '\0') {

View File

@ -94,7 +94,7 @@ TEST(Demangle, CornerCases) {
EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough. EXPECT_FALSE(Demangle(mangled, tmp, size - 2)); // Not enough.
EXPECT_FALSE(Demangle(mangled, tmp, 1)); EXPECT_FALSE(Demangle(mangled, tmp, 1));
EXPECT_FALSE(Demangle(mangled, tmp, 0)); EXPECT_FALSE(Demangle(mangled, tmp, 0));
EXPECT_FALSE(Demangle(mangled, NULL, 0)); // Should not cause SEGV. EXPECT_FALSE(Demangle(mangled, nullptr, 0)); // Should not cause SEGV.
} }
// Test handling of functions suffixed with .clone.N, which is used by GCC // Test handling of functions suffixed with .clone.N, which is used by GCC

View File

@ -1,4 +1,4 @@
// Copyright (c) 2007, Google Inc. // Copyright (c) 2023, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -48,7 +48,7 @@
// Variables of type LogSeverity are widely taken to lie in the range // Variables of type LogSeverity are widely taken to lie in the range
// [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if // [0, NUM_SEVERITIES-1]. Be careful to preserve this assumption if
// you ever need to change their values or add a new severity. // you ever need to change their values or add a new severity.
typedef int LogSeverity; using LogSeverity = int;
const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3, const int GLOG_INFO = 0, GLOG_WARNING = 1, GLOG_ERROR = 2, GLOG_FATAL = 3,
NUM_SEVERITIES = 4; NUM_SEVERITIES = 4;

View File

@ -1,4 +1,4 @@
// Copyright (c) 2022, Google Inc. // Copyright (c) 2023, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -36,11 +36,8 @@
#ifndef GLOG_LOGGING_H #ifndef GLOG_LOGGING_H
#define GLOG_LOGGING_H #define GLOG_LOGGING_H
#if @ac_cv_cxx11_chrono@ && __cplusplus >= 201103L
#include <chrono>
#endif
#include <cerrno> #include <cerrno>
#include <chrono>
#include <cstddef> #include <cstddef>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
@ -75,46 +72,23 @@
// Note: these commands below may look like "#if 1" or "#if 0", but // Note: these commands below may look like "#if 1" or "#if 0", but
// that's because they were constructed that way at ./configure time. // that's because they were constructed that way at ./configure time.
// Look at logging.h.in to see how they're calculated (based on your config). // Look at logging.h.in to see how they're calculated (based on your config).
#if @ac_cv_have_stdint_h@ #include <cstdint> // the normal place uint16_t is defined
#include <stdint.h> // the normal place uint16_t is defined
#endif
#if @ac_cv_have_systypes_h@ #if @ac_cv_have_systypes_h@
#include <sys/types.h> // the normal place u_int16_t is defined #include <sys/types.h> // the normal place u_int16_t is defined
#endif #endif
#if @ac_cv_have_inttypes_h@
#include <inttypes.h> // a third place for uint16_t or u_int16_t
#endif
#if @ac_cv_have_libgflags@ #if @ac_cv_have_libgflags@
#include <gflags/gflags.h> #include <gflags/gflags.h>
#endif #endif
#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L
#include <atomic> #include <atomic>
#elif defined(GLOG_OS_WINDOWS)
#include <Windows.h>
#endif
@ac_google_start_namespace@ @ac_google_start_namespace@
#if @ac_cv_have_stdint_h@ // the C99 format typedef std::int32_t int32;
typedef int32_t int32; typedef std::uint32_t uint32;
typedef uint32_t uint32; typedef std::int64_t int64;
typedef int64_t int64; typedef std::uint64_t uint64;
typedef uint64_t uint64;
#elif @ac_cv_have_u_int16_t@ // the BSD format
typedef int32_t int32;
typedef u_int32_t uint32;
typedef int64_t int64;
typedef u_int64_t uint64;
#elif @ac_cv_have___uint16@ // the windows (vc7) format
typedef __int32 int32;
typedef unsigned __int32 uint32;
typedef __int64 int64;
typedef unsigned __int64 uint64;
#else
#error Do not know how to define a 32-bit integer quantity on your system
#endif
#if !(@ac_cv_have_ssize_t@) #if !(@ac_cv_have_ssize_t@)
typedef ptrdiff_t ssize_t; typedef ptrdiff_t ssize_t;
@ -743,13 +717,11 @@ inline unsigned short GetReferenceableValue(unsigned short t) { return t; }
inline int GetReferenceableValue(int t) { return t; } inline int GetReferenceableValue(int t) { return t; }
inline unsigned int GetReferenceableValue(unsigned int t) { return t; } inline unsigned int GetReferenceableValue(unsigned int t) { return t; }
inline long GetReferenceableValue(long t) { return t; } inline long GetReferenceableValue(long t) { return t; }
inline unsigned long GetReferenceableValue(unsigned long t) { return t; } inline unsigned long GetReferenceableValue(unsigned long t) { return t; }
#if __cplusplus >= 201103L
inline long long GetReferenceableValue(long long t) { return t; } inline long long GetReferenceableValue(long long t) { return t; }
inline unsigned long long GetReferenceableValue(unsigned long long t) { inline unsigned long long GetReferenceableValue(unsigned long long t) {
return t; return t;
} }
#endif
// This is a dummy class to define the following operator. // This is a dummy class to define the following operator.
struct DummyClassToDefineOperator {}; struct DummyClassToDefineOperator {};
@ -782,12 +754,10 @@ void MakeCheckOpValueString(std::ostream* os, const signed char& v);
template <> GLOG_EXPORT template <> GLOG_EXPORT
void MakeCheckOpValueString(std::ostream* os, const unsigned char& v); void MakeCheckOpValueString(std::ostream* os, const unsigned char& v);
// This is required because nullptr is only present in c++ 11 and later.
#if @ac_cv_cxx11_nullptr_t@ && __cplusplus >= 201103L
// Provide printable value for nullptr_t // Provide printable value for nullptr_t
template <> GLOG_EXPORT template <>
void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& v); GLOG_EXPORT void MakeCheckOpValueString(std::ostream* os,
#endif const std::nullptr_t& v);
// Build the error message string. Specify no inlining for code size. // Build the error message string. Specify no inlining for code size.
template <typename T1, typename T2> template <typename T1, typename T2>
@ -1031,12 +1001,6 @@ PLOG_IF(FATAL, GOOGLE_PREDICT_BRANCH_NOT_TAKEN((invocation) == -1)) \
#define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__) #define LOG_OCCURRENCES LOG_EVERY_N_VARNAME(occurrences_, __LINE__)
#define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__) #define LOG_OCCURRENCES_MOD_N LOG_EVERY_N_VARNAME(occurrences_mod_n_, __LINE__)
#if @ac_cv_cxx11_constexpr@ && __cplusplus >= 201103L
#define GLOG_CONSTEXPR constexpr
#else
#define GLOG_CONSTEXPR const
#endif
#define LOG_TIME_PERIOD LOG_EVERY_N_VARNAME(timePeriod_, __LINE__) #define LOG_TIME_PERIOD LOG_EVERY_N_VARNAME(timePeriod_, __LINE__)
#define LOG_PREVIOUS_TIME_RAW LOG_EVERY_N_VARNAME(previousTimeRaw_, __LINE__) #define LOG_PREVIOUS_TIME_RAW LOG_EVERY_N_VARNAME(previousTimeRaw_, __LINE__)
#define LOG_TIME_DELTA LOG_EVERY_N_VARNAME(deltaTime_, __LINE__) #define LOG_TIME_DELTA LOG_EVERY_N_VARNAME(deltaTime_, __LINE__)
@ -1074,54 +1038,34 @@ extern "C" void AnnotateBenignRaceSized(
namespace google { namespace google {
#endif #endif
#if __cplusplus >= 201103L && @ac_cv_cxx11_chrono@ && @ac_cv_cxx11_atomic@ // Have <chrono> and <atomic> #define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \ constexpr std::chrono::nanoseconds LOG_TIME_PERIOD = \
GLOG_CONSTEXPR std::chrono::nanoseconds LOG_TIME_PERIOD = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::duration<double>(seconds)); \ std::chrono::duration_cast<std::chrono::nanoseconds>( \
static std::atomic<@ac_google_namespace@::int64> LOG_PREVIOUS_TIME_RAW; \ std::chrono::duration<double>(seconds)); \
GLOG_IFDEF_THREAD_SANITIZER( \ static std::atomic<@ac_google_namespace@ ::int64> LOG_PREVIOUS_TIME_RAW; \
AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, sizeof(@ac_google_namespace@::int64), "")); \ GLOG_IFDEF_THREAD_SANITIZER( \
GLOG_IFDEF_THREAD_SANITIZER( \ AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_TIME_PERIOD, \
AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, sizeof(@ac_google_namespace@::int64), "")); \ sizeof(@ac_google_namespace @ ::int64), "")); \
const auto LOG_CURRENT_TIME = std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now().time_since_epoch()); \ GLOG_IFDEF_THREAD_SANITIZER( \
const auto LOG_PREVIOUS_TIME = LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \ AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_PREVIOUS_TIME_RAW, \
const auto LOG_TIME_DELTA = LOG_CURRENT_TIME - std::chrono::nanoseconds(LOG_PREVIOUS_TIME); \ sizeof(@ac_google_namespace @ ::int64), "")); \
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \ const auto LOG_CURRENT_TIME = \
LOG_PREVIOUS_TIME_RAW.store(std::chrono::duration_cast<std::chrono::nanoseconds>(LOG_CURRENT_TIME).count(), std::memory_order_relaxed); \ std::chrono::duration_cast<std::chrono::nanoseconds>( \
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \ std::chrono::steady_clock::now().time_since_epoch()); \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream() const auto LOG_PREVIOUS_TIME = \
#elif defined(GLOG_OS_WINDOWS) LOG_PREVIOUS_TIME_RAW.load(std::memory_order_relaxed); \
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \ const auto LOG_TIME_DELTA = \
GLOG_CONSTEXPR LONGLONG LOG_TIME_PERIOD = (seconds) * LONGLONG(1000000000); \ LOG_CURRENT_TIME - std::chrono::nanoseconds(LOG_PREVIOUS_TIME); \
static LARGE_INTEGER LOG_PREVIOUS_TIME; \ if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
LONGLONG LOG_TIME_DELTA; \ LOG_PREVIOUS_TIME_RAW.store( \
{ \ std::chrono::duration_cast<std::chrono::nanoseconds>(LOG_CURRENT_TIME) \
LARGE_INTEGER currTime; \ .count(), \
LARGE_INTEGER freq; \ std::memory_order_relaxed); \
QueryPerformanceCounter(&currTime); \ if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
QueryPerformanceFrequency(&freq); \ @ac_google_namespace@ ::LogMessage( \
InterlockedCompareExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart, 0); \ __FILE__, __LINE__, @ac_google_namespace@ ::GLOG_##severity) \
LOG_TIME_DELTA = (currTime.QuadPart - LOG_PREVIOUS_TIME.QuadPart) * LONGLONG(1000000000) / freq.QuadPart; \ .stream()
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) InterlockedExchange64(&LOG_PREVIOUS_TIME.QuadPart, currTime.QuadPart); \
} \
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
#else
#define SOME_KIND_OF_LOG_EVERY_T(severity, seconds) \
GLOG_CONSTEXPR @ac_google_namespace@::int64 LOG_TIME_PERIOD(seconds * 1000000000); \
static @ac_google_namespace@::int64 LOG_PREVIOUS_TIME; \
@ac_google_namespace@::int64 LOG_TIME_DELTA = 0; \
{ \
timespec currentTime = {}; \
clock_gettime(CLOCK_MONOTONIC, &currentTime); \
LOG_TIME_DELTA = (currentTime.tv_sec * 1000000000 + currentTime.tv_nsec) - LOG_PREVIOUS_TIME; \
} \
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) __sync_add_and_fetch(&LOG_PREVIOUS_TIME, LOG_TIME_DELTA); \
if (LOG_TIME_DELTA > LOG_TIME_PERIOD) @ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity).stream()
#endif
#if @ac_cv_cxx11_atomic@ && __cplusplus >= 201103L
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \ #define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \ static std::atomic<int> LOG_OCCURRENCES(0), LOG_OCCURRENCES_MOD_N(0); \
GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \ GLOG_IFDEF_THREAD_SANITIZER(AnnotateBenignRaceSized(__FILE__, __LINE__, &LOG_OCCURRENCES, sizeof(int), "")); \
@ -1165,94 +1109,6 @@ namespace google {
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \ __FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream() &what_to_do).stream()
#elif defined(GLOG_OS_WINDOWS)
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
static volatile unsigned LOG_OCCURRENCES = 0; \
static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
InterlockedIncrement(&LOG_OCCURRENCES); \
if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \
InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \
if (LOG_OCCURRENCES_MOD_N == 1) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
static volatile unsigned LOG_OCCURRENCES = 0; \
static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
InterlockedIncrement(&LOG_OCCURRENCES); \
if ((condition) && \
((InterlockedIncrement(&LOG_OCCURRENCES_MOD_N), \
(LOG_OCCURRENCES_MOD_N > n && InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n))), \
LOG_OCCURRENCES_MOD_N == 1)) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
static volatile unsigned LOG_OCCURRENCES = 0; \
static volatile unsigned LOG_OCCURRENCES_MOD_N = 0; \
InterlockedIncrement(&LOG_OCCURRENCES); \
if (InterlockedIncrement(&LOG_OCCURRENCES_MOD_N) > n) \
InterlockedExchangeSubtract(&LOG_OCCURRENCES_MOD_N, n); \
if (LOG_OCCURRENCES_MOD_N == 1) \
@ac_google_namespace@::ErrnoLogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
static volatile unsigned LOG_OCCURRENCES = 0; \
if (LOG_OCCURRENCES <= n) \
InterlockedIncrement(&LOG_OCCURRENCES); \
if (LOG_OCCURRENCES <= n) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#else
#define SOME_KIND_OF_LOG_EVERY_N(severity, n, what_to_do) \
static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \
__sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \
if (LOG_OCCURRENCES_MOD_N == 1) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#define SOME_KIND_OF_LOG_IF_EVERY_N(severity, condition, n, what_to_do) \
static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
if ((condition) && \
(__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) || true) && \
((LOG_OCCURRENCES_MOD_N >= n && __sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n)) || true) && \
LOG_OCCURRENCES_MOD_N == (1 % n)) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#define SOME_KIND_OF_PLOG_EVERY_N(severity, n, what_to_do) \
static int LOG_OCCURRENCES = 0, LOG_OCCURRENCES_MOD_N = 0; \
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
if (__sync_add_and_fetch(&LOG_OCCURRENCES_MOD_N, 1) > n) \
__sync_sub_and_fetch(&LOG_OCCURRENCES_MOD_N, n); \
if (LOG_OCCURRENCES_MOD_N == 1) \
@ac_google_namespace@::ErrnoLogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#define SOME_KIND_OF_LOG_FIRST_N(severity, n, what_to_do) \
static int LOG_OCCURRENCES = 0; \
if (LOG_OCCURRENCES <= n) \
__sync_add_and_fetch(&LOG_OCCURRENCES, 1); \
if (LOG_OCCURRENCES <= n) \
@ac_google_namespace@::LogMessage( \
__FILE__, __LINE__, @ac_google_namespace@::GLOG_ ## severity, LOG_OCCURRENCES, \
&what_to_do).stream()
#endif
namespace glog_internal_namespace_ { namespace glog_internal_namespace_ {
template <bool> template <bool>
struct CompileAssert { struct CompileAssert {
@ -1575,7 +1431,7 @@ public:
void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs void SendToSyslogAndLog(); // Actually dispatch to syslog and the logs
// Call abort() or similar to perform LOG(FATAL) crash. // Call abort() or similar to perform LOG(FATAL) crash.
static void @ac_cv___attribute___noreturn@ Fail(); [[noreturn]] static void Fail();
std::ostream& stream(); std::ostream& stream();
@ -1626,7 +1482,7 @@ class GLOG_EXPORT LogMessageFatal : public LogMessage {
public: public:
LogMessageFatal(const char* file, int line); LogMessageFatal(const char* file, int line);
LogMessageFatal(const char* file, int line, const CheckOpString& result); LogMessageFatal(const char* file, int line, const CheckOpString& result);
@ac_cv___attribute___noreturn@ ~LogMessageFatal(); [[noreturn]] ~LogMessageFatal();
}; };
// A non-macro interface to the log facility; (useful // A non-macro interface to the log facility; (useful
@ -1641,17 +1497,6 @@ inline void LogAtLevel(int const severity, std::string const &msg) {
// LOG macros, 2. this macro can be used as C++ stream. // LOG macros, 2. this macro can be used as C++ stream.
#define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream() #define LOG_AT_LEVEL(severity) @ac_google_namespace@::LogMessage(__FILE__, __LINE__, severity).stream()
// Check if it's compiled in C++11 mode.
//
// GXX_EXPERIMENTAL_CXX0X is defined by gcc and clang up to at least
// gcc-4.7 and clang-3.1 (2011-12-13). __cplusplus was defined to 1
// in gcc before 4.7 (Crosstool 16) and clang before 3.1, but is
// defined according to the language version in effect thereafter.
// Microsoft Visual Studio 14 (2015) sets __cplusplus==199711 despite
// reasonably good C++11 support, so we set LANG_CXX for it and
// newer versions (_MSC_VER >= 1900).
#if (defined(__GXX_EXPERIMENTAL_CXX0X__) || __cplusplus >= 201103L || \
(defined(_MSC_VER) && _MSC_VER >= 1900)) && !defined(__UCLIBCXX_MAJOR__)
// Helper for CHECK_NOTNULL(). // Helper for CHECK_NOTNULL().
// //
// In C++11, all cases can be handled by a single function. Since the value // In C++11, all cases can be handled by a single function. Since the value
@ -1668,18 +1513,6 @@ T CheckNotNull(const char* file, int line, const char* names, T&& t) {
return std::forward<T>(t); return std::forward<T>(t);
} }
#else
// A small helper for CHECK_NOTNULL().
template <typename T>
T* CheckNotNull(const char *file, int line, const char *names, T* t) {
if (t == NULL) {
LogMessageFatal(file, line, new std::string(names));
}
return t;
}
#endif
// Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This // Allow folks to put a counter in the LOG_EVERY_X()'ed messages. This
// only works if ostream is a LogStream. If the ostream is not a // only works if ostream is a LogStream. If the ostream is not a
// LogStream you'll get an assert saying as much at runtime. // LogStream you'll get an assert saying as much at runtime.
@ -1967,7 +1800,7 @@ class GLOG_EXPORT NullStreamFatal : public NullStream {
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4722) #pragma warning(disable : 4722)
#endif // _MSC_VER #endif // _MSC_VER
@ac_cv___attribute___noreturn@ ~NullStreamFatal() throw () { _exit(EXIT_FAILURE); } [[noreturn]] ~NullStreamFatal() throw() { _exit(EXIT_FAILURE); }
#if defined(_MSC_VER) #if defined(_MSC_VER)
#pragma warning(pop) #pragma warning(pop)
#endif // _MSC_VER #endif // _MSC_VER

View File

@ -47,36 +47,16 @@
#ifndef UTIL_GTL_STL_LOGGING_INL_H_ #ifndef UTIL_GTL_STL_LOGGING_INL_H_
#define UTIL_GTL_STL_LOGGING_INL_H_ #define UTIL_GTL_STL_LOGGING_INL_H_
#if !@ac_cv_cxx_using_operator@
# error We do not support stl_logging for this compiler
#endif
#include <deque> #include <deque>
#include <list> #include <list>
#include <map> #include <map>
#include <ostream> #include <ostream>
#include <set> #include <set>
#include <unordered_map>
#include <unordered_set>
#include <utility> #include <utility>
#include <vector> #include <vector>
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
# include <unordered_map>
# include <unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
# include <tr1/unordered_map>
# include <tr1/unordered_set>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
# include <ext/hash_set>
# include <ext/hash_map>
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
# include <ext/slist>
#endif
// Forward declare these two, and define them after all the container streams // Forward declare these two, and define them after all the container streams
// operators so that we can recurse from pair -> container -> container -> pair // operators so that we can recurse from pair -> container -> container -> pair
// properly. // properly.
@ -89,7 +69,6 @@ template<class Iter>
void PrintSequence(std::ostream& out, Iter begin, Iter end); void PrintSequence(std::ostream& out, Iter begin, Iter end);
@ac_google_end_namespace@ @ac_google_end_namespace@
#define OUTPUT_TWO_ARG_CONTAINER(Sequence) \ #define OUTPUT_TWO_ARG_CONTAINER(Sequence) \
template<class T1, class T2> \ template<class T1, class T2> \
inline std::ostream& operator<<(std::ostream& out, \ inline std::ostream& operator<<(std::ostream& out, \
@ -98,12 +77,8 @@ inline std::ostream& operator<<(std::ostream& out, \
return out; \ return out; \
} }
OUTPUT_TWO_ARG_CONTAINER(std::vector) OUTPUT_TWO_ARG_CONTAINER(std::vector) OUTPUT_TWO_ARG_CONTAINER(std::deque)
OUTPUT_TWO_ARG_CONTAINER(std::deque) OUTPUT_TWO_ARG_CONTAINER(std::list)
OUTPUT_TWO_ARG_CONTAINER(std::list)
#ifdef GLOG_STL_LOGGING_FOR_EXT_SLIST
OUTPUT_TWO_ARG_CONTAINER(__gnu_cxx::slist)
#endif
#undef OUTPUT_TWO_ARG_CONTAINER #undef OUTPUT_TWO_ARG_CONTAINER
@ -115,8 +90,8 @@ inline std::ostream& operator<<(std::ostream& out, \
return out; \ return out; \
} }
OUTPUT_THREE_ARG_CONTAINER(std::set) OUTPUT_THREE_ARG_CONTAINER(std::set) OUTPUT_THREE_ARG_CONTAINER(
OUTPUT_THREE_ARG_CONTAINER(std::multiset) std::multiset)
#undef OUTPUT_THREE_ARG_CONTAINER #undef OUTPUT_THREE_ARG_CONTAINER
@ -128,20 +103,9 @@ inline std::ostream& operator<<(std::ostream& out, \
return out; \ return out; \
} }
OUTPUT_FOUR_ARG_CONTAINER(std::map) OUTPUT_FOUR_ARG_CONTAINER(std::map) OUTPUT_FOUR_ARG_CONTAINER(
OUTPUT_FOUR_ARG_CONTAINER(std::multimap) std::multimap) OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_set)
OUTPUT_FOUR_ARG_CONTAINER(std::tr1::unordered_multiset)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_set)
OUTPUT_FOUR_ARG_CONTAINER(__gnu_cxx::hash_multiset)
#endif
#undef OUTPUT_FOUR_ARG_CONTAINER #undef OUTPUT_FOUR_ARG_CONTAINER
@ -154,23 +118,16 @@ inline std::ostream& operator<<(std::ostream& out, \
} }
#if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L #if defined(GLOG_STL_LOGGING_FOR_UNORDERED) && __cplusplus >= 201103L
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map) OUTPUT_FIVE_ARG_CONTAINER(std::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap) OUTPUT_FIVE_ARG_CONTAINER(std::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_map)
OUTPUT_FIVE_ARG_CONTAINER(std::tr1::unordered_multimap)
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_map)
OUTPUT_FIVE_ARG_CONTAINER(__gnu_cxx::hash_multimap)
#endif #endif
#undef OUTPUT_FIVE_ARG_CONTAINER #undef OUTPUT_FIVE_ARG_CONTAINER
template<class First, class Second> template <class First, class Second>
inline std::ostream& operator<<(std::ostream& out, inline std::ostream& operator<<(
const std::pair<First, Second>& p) { std::ostream& out,
const std::pair<First, Second>& p) {
out << '(' << p.first << ", " << p.second << ')'; out << '(' << p.first << ", " << p.second << ')';
return out; return out;
} }

View File

@ -1,4 +1,4 @@
// Copyright (c) 1999, 2007, Google Inc. // Copyright (c) 2023, Google Inc.
// All rights reserved. // All rights reserved.
// //
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
@ -63,6 +63,8 @@
#include <glog/log_severity.h> #include <glog/log_severity.h>
#include <cstddef>
#if defined(__GNUC__) #if defined(__GNUC__)
// We emit an anonymous static int* variable at every VLOG_IS_ON(n) site. // We emit an anonymous static int* variable at every VLOG_IS_ON(n) site.
// (Normally) the first time every VLOG_IS_ON(n) site is hit, // (Normally) the first time every VLOG_IS_ON(n) site is hit,
@ -98,7 +100,7 @@ extern GLOG_EXPORT int SetVLOGLevel(const char* module_pattern, int log_level);
struct SiteFlag { struct SiteFlag {
@ac_google_namespace@::int32* level; @ac_google_namespace@::int32* level;
const char* base_name; const char* base_name;
size_t base_len; std::size_t base_len;
SiteFlag* next; SiteFlag* next;
}; };

View File

@ -35,7 +35,9 @@
#endif #endif
#define GOOGLETEST_H__ #define GOOGLETEST_H__
#include "utilities.h" #include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <cctype> #include <cctype>
#include <csetjmp> #include <csetjmp>
@ -45,11 +47,10 @@
#include <map> #include <map>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <utility>
#include <vector> #include <vector>
#include <sys/types.h> #include "utilities.h"
#include <sys/stat.h>
#include <fcntl.h>
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> # include <unistd.h>
#endif #endif
@ -270,19 +271,17 @@ static inline void RunSpecifiedBenchmarks() {
int iter_cnt = FLAGS_benchmark_iters; int iter_cnt = FLAGS_benchmark_iters;
puts("Benchmark\tTime(ns)\tIterations"); puts("Benchmark\tTime(ns)\tIterations");
for (map<string, void (*)(int)>::const_iterator iter = g_benchlist.begin(); for (auto& iter : g_benchlist) {
iter != g_benchlist.end();
++iter) {
clock_t start = clock(); clock_t start = clock();
iter->second(iter_cnt); iter.second(iter_cnt);
double elapsed_ns = (static_cast<double>(clock()) - start) / double elapsed_ns = (static_cast<double>(clock()) - start) /
CLOCKS_PER_SEC * 1000 * 1000 * 1000; CLOCKS_PER_SEC * 1000 * 1000 * 1000;
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push #pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wformat=" #pragma GCC diagnostic ignored "-Wformat="
#endif #endif
printf("%s\t%8.2lf\t%10d\n", printf("%s\t%8.2lf\t%10d\n", iter.first.c_str(), elapsed_ns / iter_cnt,
iter->first.c_str(), elapsed_ns / iter_cnt, iter_cnt); iter_cnt);
#if defined(__GNUC__) && !defined(__clang__) #if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop #pragma GCC diagnostic pop
#endif #endif
@ -296,10 +295,10 @@ static inline void RunSpecifiedBenchmarks() {
class CapturedStream { class CapturedStream {
public: public:
CapturedStream(int fd, const string & filename) : CapturedStream(int fd, string filename)
fd_(fd), : fd_(fd),
uncaptured_fd_(-1),
filename_(filename) { filename_(std::move(filename)) {
Capture(); Capture();
} }
@ -323,7 +322,7 @@ class CapturedStream {
CHECK(cap_fd != -1); CHECK(cap_fd != -1);
// Send stdout/stderr to this file // Send stdout/stderr to this file
fflush(NULL); fflush(nullptr);
CHECK(dup2(cap_fd, fd_) != -1); CHECK(dup2(cap_fd, fd_) != -1);
CHECK(close(cap_fd) != -1); CHECK(close(cap_fd) != -1);
} }
@ -332,7 +331,7 @@ class CapturedStream {
void StopCapture() { void StopCapture() {
// Restore original stream // Restore original stream
if (uncaptured_fd_ != -1) { if (uncaptured_fd_ != -1) {
fflush(NULL); fflush(nullptr);
CHECK(dup2(uncaptured_fd_, fd_) != -1); CHECK(dup2(uncaptured_fd_, fd_) != -1);
} }
} }
@ -341,7 +340,7 @@ class CapturedStream {
private: private:
int fd_; // file descriptor being captured int fd_; // file descriptor being captured
int uncaptured_fd_; // where the stream was originally being sent to int uncaptured_fd_{-1}; // where the stream was originally being sent to
string filename_; // file where stream is being saved string filename_; // file where stream is being saved
}; };
static CapturedStream * s_captured_streams[STDERR_FILENO+1]; static CapturedStream * s_captured_streams[STDERR_FILENO+1];
@ -350,7 +349,7 @@ static CapturedStream * s_captured_streams[STDERR_FILENO+1];
// filename - File where output should be stored // filename - File where output should be stored
static inline void CaptureTestOutput(int fd, const string & filename) { static inline void CaptureTestOutput(int fd, const string & filename) {
CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO)); CHECK((fd == STDOUT_FILENO) || (fd == STDERR_FILENO));
CHECK(s_captured_streams[fd] == NULL); CHECK(s_captured_streams[fd] == nullptr);
s_captured_streams[fd] = new CapturedStream(fd, filename); s_captured_streams[fd] = new CapturedStream(fd, filename);
} }
static inline void CaptureTestStdout() { static inline void CaptureTestStdout() {
@ -403,7 +402,7 @@ static inline string GetCapturedTestOutput(int fd) {
fclose(file); fclose(file);
delete cap; delete cap;
s_captured_streams[fd] = NULL; s_captured_streams[fd] = nullptr;
return content; return content;
} }
@ -479,7 +478,7 @@ static inline void StringReplace(string* str,
static inline string Munge(const string& filename) { static inline string Munge(const string& filename) {
FILE* fp = fopen(filename.c_str(), "rb"); FILE* fp = fopen(filename.c_str(), "rb");
CHECK(fp != NULL) << filename << ": couldn't open"; CHECK(fp != nullptr) << filename << ": couldn't open";
char buf[4096]; char buf[4096];
string result; string result;
while (fgets(buf, 4095, fp)) { while (fgets(buf, 4095, fp)) {
@ -487,7 +486,7 @@ static inline string Munge(const string& filename) {
const size_t str_size = 256; const size_t str_size = 256;
char null_str[str_size]; char null_str[str_size];
char ptr_str[str_size]; char ptr_str[str_size];
snprintf(null_str, str_size, "%p", static_cast<void*>(NULL)); snprintf(null_str, str_size, "%p", static_cast<void*>(nullptr));
snprintf(ptr_str, str_size, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE)); snprintf(ptr_str, str_size, "%p", reinterpret_cast<void*>(PTR_TEST_VALUE));
StringReplace(&line, "__NULLP__", null_str); StringReplace(&line, "__NULLP__", null_str);
@ -577,29 +576,20 @@ struct FlagSaver {
class Thread { class Thread {
public: public:
virtual ~Thread() {} virtual ~Thread() = default;
void SetJoinable(bool) {} void SetJoinable(bool) {}
#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN) #if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
void Start() { void Start() {
handle_ = CreateThread(NULL, handle_ = CreateThread(nullptr, 0, &Thread::InvokeThreadW, this, 0, &th_);
0,
&Thread::InvokeThreadW,
this,
0,
&th_);
CHECK(handle_) << "CreateThread"; CHECK(handle_) << "CreateThread";
} }
void Join() { void Join() {
WaitForSingleObject(handle_, INFINITE); WaitForSingleObject(handle_, INFINITE);
} }
#elif defined(HAVE_PTHREAD) #elif defined(HAVE_PTHREAD)
void Start() { void Start() { pthread_create(&th_, nullptr, &Thread::InvokeThread, this); }
pthread_create(&th_, NULL, &Thread::InvokeThread, this); void Join() { pthread_join(th_, nullptr); }
}
void Join() {
pthread_join(th_, NULL);
}
#else #else
# error No thread implementation. # error No thread implementation.
#endif #endif
@ -610,7 +600,7 @@ class Thread {
private: private:
static void* InvokeThread(void* self) { static void* InvokeThread(void* self) {
(static_cast<Thread*>(self))->Run(); (static_cast<Thread*>(self))->Run();
return NULL; return nullptr;
} }
#if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN) #if defined(GLOG_OS_WINDOWS) && !defined(GLOG_OS_CYGWIN)
@ -629,7 +619,7 @@ static inline void SleepForMilliseconds(unsigned t) {
#ifndef GLOG_OS_WINDOWS #ifndef GLOG_OS_WINDOWS
# if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L # if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309L
const struct timespec req = {0, t * 1000 * 1000}; const struct timespec req = {0, t * 1000 * 1000};
nanosleep(&req, NULL); nanosleep(&req, nullptr);
# else # else
usleep(t * 1000); usleep(t * 1000);
# endif # endif
@ -640,7 +630,7 @@ static inline void SleepForMilliseconds(unsigned t) {
// Add hook for operator new to ensure there are no memory allocation. // Add hook for operator new to ensure there are no memory allocation.
void (*g_new_hook)() = NULL; void (*g_new_hook)() = nullptr;
_END_GOOGLE_NAMESPACE_ _END_GOOGLE_NAMESPACE_
@ -655,18 +645,10 @@ void* operator new[](size_t size) GOOGLE_GLOG_THROW_BAD_ALLOC {
return ::operator new(size); return ::operator new(size);
} }
void operator delete(void* p) throw() { void operator delete(void* p) noexcept { free(p); }
free(p);
}
void operator delete(void* p, size_t) throw() { void operator delete(void* p, size_t) noexcept { ::operator delete(p); }
::operator delete(p);
}
void operator delete[](void* p) throw() { void operator delete[](void* p) noexcept { ::operator delete(p); }
::operator delete(p);
}
void operator delete[](void* p, size_t) throw() { void operator delete[](void* p, size_t) noexcept { ::operator delete(p); }
::operator delete(p);
}

View File

@ -110,7 +110,7 @@ static bool BoolFromEnv(const char *varname, bool defval) {
if (!valstr) { if (!valstr) {
return defval; return defval;
} }
return memchr("tTyY1\0", valstr[0], 6) != NULL; return memchr("tTyY1\0", valstr[0], 6) != nullptr;
} }
GLOG_DEFINE_bool(timestamp_in_logfile_name, GLOG_DEFINE_bool(timestamp_in_logfile_name,
@ -175,11 +175,11 @@ GLOG_DEFINE_string(logmailer, "",
static const char* DefaultLogDir() { static const char* DefaultLogDir() {
const char* env; const char* env;
env = getenv("GOOGLE_LOG_DIR"); env = getenv("GOOGLE_LOG_DIR");
if (env != NULL && env[0] != '\0') { if (env != nullptr && env[0] != '\0') {
return env; return env;
} }
env = getenv("TEST_TMPDIR"); env = getenv("TEST_TMPDIR");
if (env != NULL && env[0] != '\0') { if (env != nullptr && env[0] != '\0') {
return env; return env;
} }
return ""; return "";
@ -207,7 +207,7 @@ GLOG_DEFINE_bool(log_utc_time, false,
"Use UTC time for logging."); "Use UTC time for logging.");
// TODO(hamaji): consider windows // TODO(hamaji): consider windows
#define PATH_SEPARATOR '/' enum { PATH_SEPARATOR = '/' };
#ifndef HAVE_PREAD #ifndef HAVE_PREAD
#if defined(GLOG_OS_WINDOWS) #if defined(GLOG_OS_WINDOWS)
@ -277,7 +277,7 @@ static bool TerminalSupportsColor() {
#else #else
// On non-Windows platforms, we rely on the TERM variable. // On non-Windows platforms, we rely on the TERM variable.
const char* const term = getenv("TERM"); const char* const term = getenv("TERM");
if (term != NULL && term[0] != '\0') { if (term != nullptr && term[0] != '\0') {
term_supports_color = term_supports_color =
!strcmp(term, "xterm") || !strcmp(term, "xterm") ||
!strcmp(term, "xterm-color") || !strcmp(term, "xterm-color") ||
@ -346,7 +346,7 @@ static const char* GetAnsiColorCode(GLogColor color) {
case COLOR_YELLOW: return "3"; case COLOR_YELLOW: return "3";
case COLOR_DEFAULT: return ""; case COLOR_DEFAULT: return "";
}; };
return NULL; // stop warning about return type. return nullptr; // stop warning about return type.
} }
#endif // GLOG_OS_WINDOWS #endif // GLOG_OS_WINDOWS
@ -373,9 +373,10 @@ struct LogMessage::LogMessageData {
int line_; // line number where logging call is. int line_; // line number where logging call is.
void (LogMessage::*send_method_)(); // Call this in destructor to send void (LogMessage::*send_method_)(); // Call this in destructor to send
union { // At most one of these is used: union to keep the size low. union { // At most one of these is used: union to keep the size low.
LogSink* sink_; // NULL or sink to send message to LogSink* sink_; // nullptr or sink to send message to
std::vector<std::string>* outvec_; // NULL or vector to push message onto std::vector<std::string>*
std::string* message_; // NULL or string to write message into outvec_; // nullptr or vector to push message onto
std::string* message_; // nullptr or string to write message into
}; };
size_t num_prefix_chars_; // # of chars of prefix in this message 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_log_; // # of chars of msg to send to log
@ -386,8 +387,8 @@ struct LogMessage::LogMessageData {
bool first_fatal_; // true => this was first fatal msg bool first_fatal_; // true => this was first fatal msg
private: private:
LogMessageData(const LogMessageData&); LogMessageData(const LogMessageData&) = delete;
void operator=(const LogMessageData&); void operator=(const LogMessageData&) = delete;
}; };
// A mutex that allows only one thread to log at a time, to keep things from // A mutex that allows only one thread to log at a time, to keep things from
@ -417,14 +418,13 @@ const char* GetLogSeverityName(LogSeverity severity) {
static bool SendEmailInternal(const char*dest, const char *subject, static bool SendEmailInternal(const char*dest, const char *subject,
const char*body, bool use_logging); const char*body, bool use_logging);
base::Logger::~Logger() { base::Logger::~Logger() = default;
}
namespace { namespace {
// Optional user-configured callback to print custom prefixes. // Optional user-configured callback to print custom prefixes.
CustomPrefixCallback custom_prefix_callback = NULL; CustomPrefixCallback custom_prefix_callback = nullptr;
// User-provided data to pass to the callback: // User-provided data to pass to the callback:
void* custom_prefix_callback_data = NULL; void* custom_prefix_callback_data = nullptr;
} }
namespace { namespace {
@ -433,12 +433,11 @@ namespace {
class LogFileObject : public base::Logger { class LogFileObject : public base::Logger {
public: public:
LogFileObject(LogSeverity severity, const char* base_filename); LogFileObject(LogSeverity severity, const char* base_filename);
~LogFileObject(); ~LogFileObject() override;
virtual void Write(bool force_flush, // Should we force a flush here? void Write(bool force_flush, // Should we force a flush here?
time_t timestamp, // Timestamp for this entry time_t timestamp, // Timestamp for this entry
const char* message, const char* message, size_t message_len) override;
size_t message_len);
// Configuration options // Configuration options
void SetBasename(const char* basename); void SetBasename(const char* basename);
@ -446,11 +445,11 @@ class LogFileObject : public base::Logger {
void SetSymlinkBasename(const char* symlink_basename); void SetSymlinkBasename(const char* symlink_basename);
// Normal flushing routine // Normal flushing routine
virtual void Flush(); void Flush() override;
// It is the actual file length for the system loggers, // It is the actual file length for the system loggers,
// i.e., INFO, ERROR, etc. // i.e., INFO, ERROR, etc.
virtual uint32 LogSize() { uint32 LogSize() override {
MutexLock l(&lock_); MutexLock l(&lock_);
return file_length_; return file_length_;
} }
@ -468,13 +467,13 @@ class LogFileObject : public base::Logger {
string base_filename_; string base_filename_;
string symlink_basename_; string symlink_basename_;
string filename_extension_; // option users can specify (eg to add port#) string filename_extension_; // option users can specify (eg to add port#)
FILE* file_; FILE* file_{nullptr};
LogSeverity severity_; LogSeverity severity_;
uint32 bytes_since_flush_; uint32 bytes_since_flush_{0};
uint32 dropped_mem_length_; uint32 dropped_mem_length_{0};
uint32 file_length_; uint32 file_length_{0};
unsigned int rollover_attempt_; unsigned int rollover_attempt_;
int64 next_flush_time_; // cycle count at which to flush log int64 next_flush_time_{0}; // cycle count at which to flush log
WallTime start_time_; WallTime start_time_;
// Actually create a logfile using the value of base_filename_ and the // Actually create a logfile using the value of base_filename_ and the
@ -512,9 +511,9 @@ class LogCleaner {
bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const; bool IsLogLastModifiedOver(const string& filepath, unsigned int days) const;
bool enabled_; bool enabled_{false};
unsigned int overdue_days_; unsigned int overdue_days_{7};
int64 next_cleanup_time_; // cycle count at which to clean overdue log int64 next_cleanup_time_{0}; // cycle count at which to clean overdue log
}; };
LogCleaner log_cleaner; LogCleaner log_cleaner;
@ -613,8 +612,8 @@ class LogDestination {
static Mutex sink_mutex_; static Mutex sink_mutex_;
// Disallow // Disallow
LogDestination(const LogDestination&); LogDestination(const LogDestination&) = delete;
LogDestination& operator=(const LogDestination&); LogDestination& operator=(const LogDestination&) = delete;
}; };
// Errors do not get logged to email by default. // Errors do not get logged to email by default.
@ -623,7 +622,7 @@ LogSeverity LogDestination::email_logging_severity_ = 99999;
string LogDestination::addresses_; string LogDestination::addresses_;
string LogDestination::hostname_; string LogDestination::hostname_;
vector<LogSink*>* LogDestination::sinks_ = NULL; vector<LogSink*>* LogDestination::sinks_ = nullptr;
Mutex LogDestination::sink_mutex_; Mutex LogDestination::sink_mutex_;
bool LogDestination::terminal_supports_color_ = TerminalSupportsColor(); bool LogDestination::terminal_supports_color_ = TerminalSupportsColor();
@ -666,7 +665,7 @@ inline void LogDestination::FlushLogFilesUnsafe(int min_severity) {
// about it // about it
for (int i = min_severity; i < NUM_SEVERITIES; i++) { for (int i = min_severity; i < NUM_SEVERITIES; i++) {
LogDestination* log = log_destinations_[i]; LogDestination* log = log_destinations_[i];
if (log != NULL) { if (log != nullptr) {
// Flush the base fileobject_ logger directly instead of going // Flush the base fileobject_ logger directly instead of going
// through any wrappers to reduce chance of deadlock. // through any wrappers to reduce chance of deadlock.
log->fileobject_.FlushUnlocked(); log->fileobject_.FlushUnlocked();
@ -680,7 +679,7 @@ inline void LogDestination::FlushLogFiles(int min_severity) {
MutexLock l(&log_mutex); MutexLock l(&log_mutex);
for (int i = min_severity; i < NUM_SEVERITIES; i++) { for (int i = min_severity; i < NUM_SEVERITIES; i++) {
LogDestination* log = log_destination(i); LogDestination* log = log_destination(i);
if (log != NULL) { if (log != nullptr) {
log->logger_->Flush(); log->logger_->Flush();
} }
} }
@ -921,7 +920,7 @@ inline void LogDestination::WaitForSinks(LogMessage::LogMessageData* data) {
const bool send_to_sink = const bool send_to_sink =
(data->send_method_ == &LogMessage::SendToSink) || (data->send_method_ == &LogMessage::SendToSink) ||
(data->send_method_ == &LogMessage::SendToSinkAndLog); (data->send_method_ == &LogMessage::SendToSinkAndLog);
if (send_to_sink && data->sink_ != NULL) { if (send_to_sink && data->sink_ != nullptr) {
data->sink_->WaitTillSent(); data->sink_->WaitTillSent();
} }
} }
@ -931,19 +930,19 @@ LogDestination* LogDestination::log_destinations_[NUM_SEVERITIES];
inline LogDestination* LogDestination::log_destination(LogSeverity severity) { inline LogDestination* LogDestination::log_destination(LogSeverity severity) {
assert(severity >=0 && severity < NUM_SEVERITIES); assert(severity >=0 && severity < NUM_SEVERITIES);
if (!log_destinations_[severity]) { if (!log_destinations_[severity]) {
log_destinations_[severity] = new LogDestination(severity, NULL); log_destinations_[severity] = new LogDestination(severity, nullptr);
} }
return log_destinations_[severity]; return log_destinations_[severity];
} }
void LogDestination::DeleteLogDestinations() { void LogDestination::DeleteLogDestinations() {
for (int severity = 0; severity < NUM_SEVERITIES; ++severity) { for (auto& log_destination : log_destinations_) {
delete log_destinations_[severity]; delete log_destination;
log_destinations_[severity] = NULL; log_destination = nullptr;
} }
MutexLock l(&sink_mutex_); MutexLock l(&sink_mutex_);
delete sinks_; delete sinks_;
sinks_ = NULL; sinks_ = nullptr;
} }
namespace { namespace {
@ -976,30 +975,26 @@ string PrettyDuration(int secs) {
return result.str(); return result.str();
} }
LogFileObject::LogFileObject(LogSeverity severity, const char* base_filename)
: base_filename_selected_(base_filename != nullptr),
base_filename_((base_filename != nullptr) ? base_filename : ""),
symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()),
filename_extension_(),
LogFileObject::LogFileObject(LogSeverity severity, severity_(severity),
const char* base_filename)
: base_filename_selected_(base_filename != NULL), rollover_attempt_(kRolloverAttemptFrequency - 1),
base_filename_((base_filename != NULL) ? base_filename : ""),
symlink_basename_(glog_internal_namespace_::ProgramInvocationShortName()), start_time_(WallTime_Now()) {
filename_extension_(),
file_(NULL),
severity_(severity),
bytes_since_flush_(0),
dropped_mem_length_(0),
file_length_(0),
rollover_attempt_(kRolloverAttemptFrequency-1),
next_flush_time_(0),
start_time_(WallTime_Now()) {
assert(severity >= 0); assert(severity >= 0);
assert(severity < NUM_SEVERITIES); assert(severity < NUM_SEVERITIES);
} }
LogFileObject::~LogFileObject() { LogFileObject::~LogFileObject() {
MutexLock l(&lock_); MutexLock l(&lock_);
if (file_ != NULL) { if (file_ != nullptr) {
fclose(file_); fclose(file_);
file_ = NULL; file_ = nullptr;
} }
} }
@ -1008,9 +1003,9 @@ void LogFileObject::SetBasename(const char* basename) {
base_filename_selected_ = true; base_filename_selected_ = true;
if (base_filename_ != basename) { if (base_filename_ != basename) {
// Get rid of old log file since we are changing names // Get rid of old log file since we are changing names
if (file_ != NULL) { if (file_ != nullptr) {
fclose(file_); fclose(file_);
file_ = NULL; file_ = nullptr;
rollover_attempt_ = kRolloverAttemptFrequency-1; rollover_attempt_ = kRolloverAttemptFrequency-1;
} }
base_filename_ = basename; base_filename_ = basename;
@ -1021,9 +1016,9 @@ void LogFileObject::SetExtension(const char* ext) {
MutexLock l(&lock_); MutexLock l(&lock_);
if (filename_extension_ != ext) { if (filename_extension_ != ext) {
// Get rid of old log file since we are changing names // Get rid of old log file since we are changing names
if (file_ != NULL) { if (file_ != nullptr) {
fclose(file_); fclose(file_);
file_ = NULL; file_ = nullptr;
rollover_attempt_ = kRolloverAttemptFrequency-1; rollover_attempt_ = kRolloverAttemptFrequency-1;
} }
filename_extension_ = ext; filename_extension_ = ext;
@ -1041,7 +1036,7 @@ void LogFileObject::Flush() {
} }
void LogFileObject::FlushUnlocked(){ void LogFileObject::FlushUnlocked(){
if (file_ != NULL) { if (file_ != nullptr) {
fflush(file_); fflush(file_);
bytes_since_flush_ = 0; bytes_since_flush_ = 0;
} }
@ -1076,9 +1071,10 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
// locks are released on unlock or close() automatically, only after log is // locks are released on unlock or close() automatically, only after log is
// released. // released.
// This will work after a fork as it is not inherited (not stored in the fd). // This will work after a fork as it is not inherited (not stored in the fd).
// Lock will not be lost because the file is opened with exclusive lock (write) // Lock will not be lost because the file is opened with exclusive lock
// and we will never read from it inside the process. // (write) and we will never read from it inside the process.
// TODO windows implementation of this (as flock is not available on mingw). // TODO: windows implementation of this (as flock is not available on
// mingw).
static struct flock w_lock; static struct flock w_lock;
w_lock.l_type = F_WRLCK; w_lock.l_type = F_WRLCK;
@ -1095,9 +1091,9 @@ bool LogFileObject::CreateLogfile(const string& time_pid_string) {
//fdopen in append mode so if the file exists it will fseek to the end //fdopen in append mode so if the file exists it will fseek to the end
file_ = fdopen(fd, "a"); // Make a FILE*. file_ = fdopen(fd, "a"); // Make a FILE*.
if (file_ == NULL) { // Man, we're screwed! if (file_ == nullptr) { // Man, we're screwed!
close(fd); close(fd);
if (FLAGS_timestamp_in_logfile_name) { if (FLAGS_timestamp_in_logfile_name) {
unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it. unlink(filename); // Erase the half-baked evidence: an unusable log file, only if we just created it.
} }
return false; return false;
@ -1164,14 +1160,14 @@ void LogFileObject::Write(bool force_flush,
} }
if (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) { if (file_length_ >> 20U >= MaxLogSize() || PidHasChanged()) {
if (file_ != NULL) fclose(file_); if (file_ != nullptr) fclose(file_);
file_ = NULL; file_ = nullptr;
file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0; file_length_ = bytes_since_flush_ = dropped_mem_length_ = 0;
rollover_attempt_ = kRolloverAttemptFrequency - 1; rollover_attempt_ = kRolloverAttemptFrequency - 1;
} }
// If there's no destination file, make one before outputting // If there's no destination file, make one before outputting
if (file_ == NULL) { if (file_ == nullptr) {
// Try to rollover the log file every 32 log messages. The only time // Try to rollover the log file every 32 log messages. The only time
// this could matter would be when we have trouble creating the log // this could matter would be when we have trouble creating the log
// file. If that happens, we'll lose lots of log messages, of course! // file. If that happens, we'll lose lots of log messages, of course!
@ -1239,10 +1235,8 @@ void LogFileObject::Write(bool force_flush,
// Go through the list of dirs, and try to create the log file in each // Go through the list of dirs, and try to create the log file in each
// until we succeed or run out of options // until we succeed or run out of options
bool success = false; bool success = false;
for (vector<string>::const_iterator dir = log_dirs.begin(); for (const auto& log_dir : log_dirs) {
dir != log_dirs.end(); base_filename_ = log_dir + "/" + stripped_filename;
++dir) {
base_filename_ = *dir + "/" + stripped_filename;
if ( CreateLogfile(time_pid_string) ) { if ( CreateLogfile(time_pid_string) ) {
success = true; success = true;
break; break;
@ -1353,7 +1347,7 @@ void LogFileObject::Write(bool force_flush,
} }
} }
LogCleaner::LogCleaner() : enabled_(false), overdue_days_(7), next_cleanup_time_(0) {} LogCleaner::LogCleaner() = default;
void LogCleaner::Enable(unsigned int overdue_days) { void LogCleaner::Enable(unsigned int overdue_days) {
enabled_ = true; enabled_ = true;
@ -1393,17 +1387,15 @@ void LogCleaner::Run(bool base_filename_selected,
string dir = base_filename.substr(0, pos + 1); string dir = base_filename.substr(0, pos + 1);
dirs.push_back(dir); dirs.push_back(dir);
} else { } else {
dirs.push_back("."); dirs.emplace_back(".");
} }
} }
for (size_t i = 0; i < dirs.size(); i++) { for (auto& dir : dirs) {
vector<string> logs = GetOverdueLogNames(dirs[i], vector<string> logs = GetOverdueLogNames(dir, overdue_days_, base_filename,
overdue_days_,
base_filename,
filename_extension); filename_extension);
for (size_t j = 0; j < logs.size(); j++) { for (auto& log : logs) {
static_cast<void>(unlink(logs[j].c_str())); static_cast<void>(unlink(log.c_str()));
} }
} }
} }
@ -1457,9 +1449,7 @@ bool LogCleaner::IsLogFromCurrentProject(const string& filepath,
possible_dir_delim + sizeof(possible_dir_delim); possible_dir_delim + sizeof(possible_dir_delim);
size_t real_filepath_size = filepath.size(); size_t real_filepath_size = filepath.size();
for (size_t i = 0; i < base_filename.size(); ++i) { for (char c : base_filename) {
const char& c = base_filename[i];
if (cleaned_base_filename.empty()) { if (cleaned_base_filename.empty()) {
cleaned_base_filename += c; cleaned_base_filename += c;
} else if (std::find(possible_dir_delim, dir_delim_end, c) == } else if (std::find(possible_dir_delim, dir_delim_end, c) ==
@ -1532,7 +1522,7 @@ bool LogCleaner::IsLogLastModifiedOver(const string& filepath,
if (stat(filepath.c_str(), &file_stat) == 0) { if (stat(filepath.c_str(), &file_stat) == 0) {
const time_t seconds_in_a_day = 60 * 60 * 24; const time_t seconds_in_a_day = 60 * 60 * 24;
time_t last_modified_time = file_stat.st_mtime; time_t last_modified_time = file_stat.st_mtime;
time_t current_time = time(NULL); time_t current_time = time(nullptr);
return difftime(current_time, last_modified_time) > days * seconds_in_a_day; return difftime(current_time, last_modified_time) > days * seconds_in_a_day;
} }
@ -1558,16 +1548,11 @@ static LogMessage::LogMessageData fatal_msg_data_shared;
// Static thread-local log data space to use, because typically at most one // Static thread-local log data space to use, because typically at most one
// LogMessageData object exists (in this case glog makes zero heap memory // LogMessageData object exists (in this case glog makes zero heap memory
// allocations). // allocations).
static GLOG_THREAD_LOCAL_STORAGE bool thread_data_available = true; static thread_local bool thread_data_available = true;
#if defined(HAVE_ALIGNED_STORAGE) && __cplusplus >= 201103L static thread_local std::aligned_storage<
static GLOG_THREAD_LOCAL_STORAGE sizeof(LogMessage::LogMessageData),
std::aligned_storage<sizeof(LogMessage::LogMessageData), alignof(LogMessage::LogMessageData)>::type thread_msg_data;
alignof(LogMessage::LogMessageData)>::type thread_msg_data;
#else
static GLOG_THREAD_LOCAL_STORAGE
char thread_msg_data[sizeof(void*) + sizeof(LogMessage::LogMessageData)];
#endif // HAVE_ALIGNED_STORAGE
#endif // defined(GLOG_THREAD_LOCAL_STORAGE) #endif // defined(GLOG_THREAD_LOCAL_STORAGE)
LogMessage::LogMessageData::LogMessageData() LogMessage::LogMessageData::LogMessageData()
@ -1576,70 +1561,59 @@ LogMessage::LogMessageData::LogMessageData()
LogMessage::LogMessage(const char* file, int line, LogSeverity severity, LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
int64 ctr, void (LogMessage::*send_method)()) int64 ctr, void (LogMessage::*send_method)())
: allocated_(NULL) { : allocated_(nullptr) {
Init(file, line, severity, send_method); Init(file, line, severity, send_method);
data_->stream_.set_ctr(ctr); data_->stream_.set_ctr(ctr);
} }
LogMessage::LogMessage(const char* file, int line, LogMessage::LogMessage(const char* file, int line, const CheckOpString& result)
const CheckOpString& result) : allocated_(nullptr) {
: allocated_(NULL) {
Init(file, line, GLOG_FATAL, &LogMessage::SendToLog); Init(file, line, GLOG_FATAL, &LogMessage::SendToLog);
stream() << "Check failed: " << (*result.str_) << " "; stream() << "Check failed: " << (*result.str_) << " ";
} }
LogMessage::LogMessage(const char* file, int line) LogMessage::LogMessage(const char* file, int line) : allocated_(nullptr) {
: allocated_(NULL) {
Init(file, line, GLOG_INFO, &LogMessage::SendToLog); 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) { : allocated_(nullptr) {
Init(file, line, severity, &LogMessage::SendToLog); Init(file, line, severity, &LogMessage::SendToLog);
} }
LogMessage::LogMessage(const char* file, int line, LogSeverity severity, 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) { : allocated_(nullptr) {
Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog : Init(file, line, severity, also_send_to_log ? &LogMessage::SendToSinkAndLog :
&LogMessage::SendToSink); &LogMessage::SendToSink);
data_->sink_ = sink; // override Init()'s setting to NULL data_->sink_ = sink; // override Init()'s setting to nullptr
} }
LogMessage::LogMessage(const char* file, int line, LogSeverity severity, LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
vector<string> *outvec) vector<string>* outvec)
: allocated_(NULL) { : allocated_(nullptr) {
Init(file, line, severity, &LogMessage::SaveOrSendToLog); Init(file, line, severity, &LogMessage::SaveOrSendToLog);
data_->outvec_ = outvec; // override Init()'s setting to NULL data_->outvec_ = outvec; // override Init()'s setting to nullptr
} }
LogMessage::LogMessage(const char* file, int line, LogSeverity severity, LogMessage::LogMessage(const char* file, int line, LogSeverity severity,
string *message) string* message)
: allocated_(NULL) { : allocated_(nullptr) {
Init(file, line, severity, &LogMessage::WriteToStringAndLog); Init(file, line, severity, &LogMessage::WriteToStringAndLog);
data_->message_ = message; // override Init()'s setting to NULL data_->message_ = message; // override Init()'s setting to nullptr
} }
void LogMessage::Init(const char* file, void LogMessage::Init(const char* file,
int line, int line,
LogSeverity severity, LogSeverity severity,
void (LogMessage::*send_method)()) { void (LogMessage::*send_method)()) {
allocated_ = NULL; allocated_ = nullptr;
if (severity != GLOG_FATAL || !exit_on_dfatal) { if (severity != GLOG_FATAL || !exit_on_dfatal) {
#ifdef GLOG_THREAD_LOCAL_STORAGE #ifdef GLOG_THREAD_LOCAL_STORAGE
// No need for locking, because this is thread local. // No need for locking, because this is thread local.
if (thread_data_available) { if (thread_data_available) {
thread_data_available = false; thread_data_available = false;
#ifdef HAVE_ALIGNED_STORAGE
data_ = new (&thread_msg_data) LogMessageData; data_ = new (&thread_msg_data) LogMessageData;
#else
const uintptr_t kAlign = sizeof(void*) - 1;
char* align_ptr =
reinterpret_cast<char*>(reinterpret_cast<uintptr_t>(thread_msg_data + kAlign) & ~kAlign);
data_ = new (align_ptr) LogMessageData;
assert(reinterpret_cast<uintptr_t>(align_ptr) % sizeof(void*) == 0);
#endif
} else { } else {
allocated_ = new LogMessageData(); allocated_ = new LogMessageData();
data_ = allocated_; data_ = allocated_;
@ -1665,10 +1639,10 @@ void LogMessage::Init(const char* file,
data_->severity_ = severity; data_->severity_ = severity;
data_->line_ = line; data_->line_ = line;
data_->send_method_ = send_method; data_->send_method_ = send_method;
data_->sink_ = NULL; data_->sink_ = nullptr;
data_->outvec_ = NULL; data_->outvec_ = nullptr;
WallTime now = WallTime_Now(); WallTime now = WallTime_Now();
time_t timestamp_now = static_cast<time_t>(now); auto timestamp_now = static_cast<time_t>(now);
logmsgtime_ = LogMessageTime(timestamp_now, now); logmsgtime_ = LogMessageTime(timestamp_now, now);
data_->num_chars_to_log_ = 0; data_->num_chars_to_log_ = 0;
@ -1682,36 +1656,29 @@ void LogMessage::Init(const char* file,
// (log level, GMT year, month, date, time, thread_id, file basename, line) // (log level, GMT year, month, date, time, thread_id, file basename, line)
// We exclude the thread_id for the default thread. // We exclude the thread_id for the default thread.
if (FLAGS_log_prefix && (line != kNoLogPrefix)) { if (FLAGS_log_prefix && (line != kNoLogPrefix)) {
std::ios saved_fmt(NULL); std::ios saved_fmt(nullptr);
saved_fmt.copyfmt(stream()); saved_fmt.copyfmt(stream());
stream().fill('0'); stream().fill('0');
if (custom_prefix_callback == NULL) { if (custom_prefix_callback == nullptr) {
stream() << LogSeverityNames[severity][0]; stream() << LogSeverityNames[severity][0];
if (FLAGS_log_year_in_prefix) { if (FLAGS_log_year_in_prefix) {
stream() << setw(4) << 1900 + logmsgtime_.year(); stream() << setw(4) << 1900 + logmsgtime_.year();
}
stream() << setw(2) << 1 + logmsgtime_.month()
<< setw(2) << logmsgtime_.day()
<< ' '
<< setw(2) << logmsgtime_.hour() << ':'
<< setw(2) << logmsgtime_.min() << ':'
<< setw(2) << logmsgtime_.sec() << "."
<< setw(6) << logmsgtime_.usec()
<< ' '
<< setfill(' ') << setw(5)
<< static_cast<unsigned int>(GetTID()) << setfill('0')
<< ' '
<< data_->basename_ << ':' << data_->line_ << "] ";
} else {
custom_prefix_callback(
stream(),
LogMessageInfo(LogSeverityNames[severity],
data_->basename_, data_->line_, GetTID(),
logmsgtime_),
custom_prefix_callback_data
);
stream() << " ";
} }
stream() << setw(2) << 1 + logmsgtime_.month() << setw(2)
<< logmsgtime_.day() << ' ' << setw(2) << logmsgtime_.hour()
<< ':' << setw(2) << logmsgtime_.min() << ':' << setw(2)
<< logmsgtime_.sec() << "." << setw(6) << logmsgtime_.usec()
<< ' ' << setfill(' ') << setw(5)
<< static_cast<unsigned int>(GetTID()) << setfill('0') << ' '
<< data_->basename_ << ':' << data_->line_ << "] ";
} else {
custom_prefix_callback(
stream(),
LogMessageInfo(LogSeverityNames[severity], data_->basename_,
data_->line_, GetTID(), logmsgtime_),
custom_prefix_callback_data);
stream() << " ";
}
stream().copyfmt(saved_fmt); stream().copyfmt(saved_fmt);
} }
data_->num_prefix_chars_ = data_->stream_.pcount(); data_->num_prefix_chars_ = data_->stream_.pcount();
@ -1905,9 +1872,9 @@ void LogMessage::SendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
} }
if (!FLAGS_logtostderr && !FLAGS_logtostdout) { if (!FLAGS_logtostderr && !FLAGS_logtostdout) {
for (int i = 0; i < NUM_SEVERITIES; ++i) { for (auto& log_destination : LogDestination::log_destinations_) {
if (LogDestination::log_destinations_[i]) { if (log_destination) {
LogDestination::log_destinations_[i]->logger_->Write(true, 0, "", 0); log_destination->logger_->Write(true, 0, "", 0);
} }
} }
} }
@ -1961,7 +1928,7 @@ void LogMessage::Fail() {
// L >= log_mutex (callers must hold the log_mutex). // L >= log_mutex (callers must hold the log_mutex).
void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { void LogMessage::SendToSink() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
if (data_->sink_ != NULL) { if (data_->sink_ != nullptr) {
RAW_DCHECK(data_->num_chars_to_log_ > 0 && RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_, data_->sink_->send(data_->severity_, data_->fullname_, data_->basename_,
@ -1980,7 +1947,7 @@ void LogMessage::SendToSinkAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
// L >= log_mutex (callers must hold the log_mutex). // L >= log_mutex (callers must hold the log_mutex).
void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
if (data_->outvec_ != NULL) { if (data_->outvec_ != nullptr) {
RAW_DCHECK(data_->num_chars_to_log_ > 0 && RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
// Omit prefix of message and trailing newline when recording in outvec_. // Omit prefix of message and trailing newline when recording in outvec_.
@ -1993,7 +1960,7 @@ void LogMessage::SaveOrSendToLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
} }
void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) { void LogMessage::WriteToStringAndLog() EXCLUSIVE_LOCKS_REQUIRED(log_mutex) {
if (data_->message_ != NULL) { if (data_->message_ != nullptr) {
RAW_DCHECK(data_->num_chars_to_log_ > 0 && RAW_DCHECK(data_->num_chars_to_log_ > 0 &&
data_->message_text_[data_->num_chars_to_log_-1] == '\n', ""); data_->message_text_[data_->num_chars_to_log_-1] == '\n', "");
// Omit prefix of message and trailing newline when writing to message_. // Omit prefix of message and trailing newline when writing to message_.
@ -2018,8 +1985,8 @@ void LogMessage::SendToSyslogAndLog() {
// This array maps Google severity levels to syslog levels // This array maps Google severity levels to syslog levels
const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG }; const int SEVERITY_TO_LEVEL[] = { LOG_INFO, LOG_WARNING, LOG_ERR, LOG_EMERG };
syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)], "%.*s", syslog(LOG_USER | SEVERITY_TO_LEVEL[static_cast<int>(data_->severity_)],
int(data_->num_chars_to_syslog_), "%.*s", static_cast<int>(data_->num_chars_to_syslog_),
data_->message_text_ + data_->num_prefix_chars_); data_->message_text_ + data_->num_prefix_chars_);
SendToLog(); SendToLog();
#else #else
@ -2049,7 +2016,7 @@ ostream& operator<<(ostream &os, const PRIVATE_Counter&) {
#ifdef DISABLE_RTTI #ifdef DISABLE_RTTI
LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os); LogMessage::LogStream *log = static_cast<LogMessage::LogStream*>(&os);
#else #else
LogMessage::LogStream *log = dynamic_cast<LogMessage::LogStream*>(&os); auto* log = dynamic_cast<LogMessage::LogStream*>(&os);
#endif #endif
CHECK(log && log == log->self()) CHECK(log && log == log->self())
<< "You must not use COUNTER with non-glog ostream"; << "You must not use COUNTER with non-glog ostream";
@ -2085,8 +2052,7 @@ void SetLogSymlink(LogSeverity severity, const char* symlink_basename) {
LogDestination::SetLogSymlink(severity, symlink_basename); LogDestination::SetLogSymlink(severity, symlink_basename);
} }
LogSink::~LogSink() { LogSink::~LogSink() = default;
}
void LogSink::send(LogSeverity severity, const char* full_filename, void LogSink::send(LogSeverity severity, const char* full_filename,
const char* base_filename, int line, const char* base_filename, int line,
@ -2268,9 +2234,9 @@ static bool SendEmailInternal(const char*dest, const char *subject,
} }
FILE* pipe = popen(cmd.c_str(), "w"); FILE* pipe = popen(cmd.c_str(), "w");
if (pipe != NULL) { if (pipe != nullptr) {
// Add the body if we have one // Add the body if we have one
if (body) { if (body) {
fwrite(body, sizeof(char), strlen(body), pipe); fwrite(body, sizeof(char), strlen(body), pipe);
} }
bool ok = pclose(pipe) != -1; bool ok = pclose(pipe) != -1;
@ -2334,8 +2300,7 @@ static void GetTempDirectories(vector<string>* list) {
"/tmp", "/tmp",
}; };
for (size_t i = 0; i < ARRAYSIZE(candidates); i++) { for (auto d : candidates) {
const char *d = candidates[i];
if (!d) continue; // Empty env var if (!d) continue; // Empty env var
// Make sure we don't surprise anyone who's expecting a '/' // Make sure we don't surprise anyone who's expecting a '/'
@ -2359,7 +2324,7 @@ static vector<string>* logging_directories_list;
const vector<string>& GetLoggingDirectories() { const vector<string>& GetLoggingDirectories() {
// Not strictly thread-safe but we're called early in InitGoogle(). // Not strictly thread-safe but we're called early in InitGoogle().
if (logging_directories_list == NULL) { if (logging_directories_list == nullptr) {
logging_directories_list = new vector<string>; logging_directories_list = new vector<string>;
if ( !FLAGS_log_dir.empty() ) { if ( !FLAGS_log_dir.empty() ) {
@ -2384,12 +2349,12 @@ void TestOnly_ClearLoggingDirectoriesList() {
fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be " fprintf(stderr, "TestOnly_ClearLoggingDirectoriesList should only be "
"called from test code.\n"); "called from test code.\n");
delete logging_directories_list; delete logging_directories_list;
logging_directories_list = NULL; logging_directories_list = nullptr;
} }
void GetExistingTempDirectories(vector<string>* list) { void GetExistingTempDirectories(vector<string>* list) {
GetTempDirectories(list); GetTempDirectories(list);
vector<string>::iterator i_dir = list->begin(); auto i_dir = list->begin();
while( i_dir != list->end() ) { while( i_dir != list->end() ) {
// zero arg to access means test for existence; no constant // zero arg to access means test for existence; no constant
// defined on windows // defined on windows
@ -2492,18 +2457,19 @@ void TruncateStdoutStderr() {
// Helper functions for string comparisons. // Helper functions for string comparisons.
#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \ #define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
string* Check##func##expected##Impl(const char* s1, const char* s2, \ string* Check##func##expected##Impl(const char* s1, const char* s2, \
const char* names) { \ const char* names) { \
bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \ bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
if (equal == expected) return NULL; \ if (equal == expected) \
else { \ return nullptr; \
ostringstream ss; \ else { \
if (!s1) s1 = ""; \ ostringstream ss; \
if (!s2) s2 = ""; \ if (!s1) s1 = ""; \
if (!s2) s2 = ""; \
ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \ ss << #name " failed: " << names << " (" << s1 << " vs. " << s2 << ")"; \
return new string(ss.str()); \ return new string(ss.str()); \
} \ } \
} }
DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true) DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false) DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
@ -2513,7 +2479,7 @@ DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
int posix_strerror_r(int err, char *buf, size_t len) { int posix_strerror_r(int err, char *buf, size_t len) {
// Sanity check input parameters // Sanity check input parameters
if (buf == NULL || len <= 0) { if (buf == nullptr || len <= 0) {
errno = EINVAL; errno = EINVAL;
return -1; return -1;
} }
@ -2632,12 +2598,10 @@ void MakeCheckOpValueString(std::ostream* os, const unsigned char& v) {
} }
} }
#if defined(HAVE_CXX11_NULLPTR_T) && __cplusplus >= 201103L
template <> template <>
void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) { void MakeCheckOpValueString(std::ostream* os, const std::nullptr_t& /*v*/) {
(*os) << "nullptr"; (*os) << "nullptr";
} }
#endif // defined(HAVE_CXX11_NULLPTR_T)
void InitGoogleLogging(const char* argv0) { void InitGoogleLogging(const char* argv0) {
glog_internal_namespace_::InitGoogleLoggingUtilities(argv0); glog_internal_namespace_::InitGoogleLoggingUtilities(argv0);
@ -2655,7 +2619,7 @@ void ShutdownGoogleLogging() {
glog_internal_namespace_::ShutdownGoogleLoggingUtilities(); glog_internal_namespace_::ShutdownGoogleLoggingUtilities();
LogDestination::DeleteLogDestinations(); LogDestination::DeleteLogDestinations();
delete logging_directories_list; delete logging_directories_list;
logging_directories_list = NULL; logging_directories_list = nullptr;
} }
void EnableLogCleaner(unsigned int overdue_days) { void EnableLogCleaner(unsigned int overdue_days) {
@ -2676,10 +2640,11 @@ LogMessageTime::LogMessageTime(std::tm t) {
LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) { LogMessageTime::LogMessageTime(std::time_t timestamp, WallTime now) {
std::tm t; std::tm t;
if (FLAGS_log_utc_time) if (FLAGS_log_utc_time) {
gmtime_r(&timestamp, &t); gmtime_r(&timestamp, &t);
else } else {
localtime_r(&timestamp, &t); localtime_r(&timestamp, &t);
}
init(t, timestamp, now); init(t, timestamp, now);
} }

View File

@ -187,7 +187,7 @@ BENCHMARK(BM_vlog)
void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) { void PrefixAttacher(std::ostream &s, const LogMessageInfo &l, void* data) {
// Assert that `data` contains the expected contents before producing the // Assert that `data` contains the expected contents before producing the
// prefix (otherwise causing the tests to fail): // prefix (otherwise causing the tests to fail):
if (data == NULL || *static_cast<string*>(data) != "good data") { if (data == nullptr || *static_cast<string*>(data) != "good data") {
return; return;
} }
@ -213,13 +213,13 @@ int main(int argc, char **argv) {
// Make sure stderr is not buffered as stderr seems to be buffered // Make sure stderr is not buffered as stderr seems to be buffered
// on recent windows. // on recent windows.
setbuf(stderr, NULL); setbuf(stderr, nullptr);
// Test some basics before InitGoogleLogging: // Test some basics before InitGoogleLogging:
CaptureTestStderr(); CaptureTestStderr();
LogWithLevels(FLAGS_v, FLAGS_stderrthreshold, LogWithLevels(FLAGS_v, FLAGS_stderrthreshold,
FLAGS_logtostderr, FLAGS_alsologtostderr); FLAGS_logtostderr, FLAGS_alsologtostderr);
LogWithLevels(0, 0, 0, 0); // simulate "before global c-tors" LogWithLevels(0, 0, false, false); // simulate "before global c-tors"
const string early_stderr = GetCapturedTestStderr(); const string early_stderr = GetCapturedTestStderr();
EXPECT_FALSE(IsGoogleLoggingInitialized()); EXPECT_FALSE(IsGoogleLoggingInitialized());
@ -359,9 +359,7 @@ struct NewHook {
NewHook() { NewHook() {
g_new_hook = &NoAllocNewHook; g_new_hook = &NoAllocNewHook;
} }
~NewHook() { ~NewHook() { g_new_hook = nullptr; }
g_new_hook = NULL;
}
}; };
TEST(DeathNoAllocNewHook, logging) { TEST(DeathNoAllocNewHook, logging) {
@ -373,7 +371,7 @@ TEST(DeathNoAllocNewHook, logging) {
} }
void TestRawLogging() { void TestRawLogging() {
string* foo = new string("foo "); auto* foo = new string("foo ");
string huge_str(50000, 'a'); string huge_str(50000, 'a');
FlagSaver saver; FlagSaver saver;
@ -388,7 +386,7 @@ void TestRawLogging() {
RAW_LOG(INFO, "%s", const_s); RAW_LOG(INFO, "%s", const_s);
void* p = reinterpret_cast<void*>(PTR_TEST_VALUE); void* p = reinterpret_cast<void*>(PTR_TEST_VALUE);
RAW_LOG(INFO, "ptr %p", p); RAW_LOG(INFO, "ptr %p", p);
p = NULL; p = nullptr;
RAW_LOG(INFO, "ptr %p", p); RAW_LOG(INFO, "ptr %p", p);
int j = 1000; int j = 1000;
RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j); RAW_LOG(ERROR, "%s%d%c%010d%s%1x", foo->c_str(), j, ' ', j, " ", j);
@ -531,7 +529,7 @@ TEST(DeathRawCHECK, logging) {
void TestLogString() { void TestLogString() {
vector<string> errors; vector<string> errors;
vector<string> *no_errors = NULL; vector<string>* no_errors = nullptr;
LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info"; LOG_STRING(INFO, &errors) << "LOG_STRING: " << "collected info";
LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning"; LOG_STRING(WARNING, &errors) << "LOG_STRING: " << "collected warning";
@ -539,16 +537,17 @@ void TestLogString() {
LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info"; LOG_STRING(INFO, no_errors) << "LOG_STRING: " << "reported info";
LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning"; LOG_STRING(WARNING, no_errors) << "LOG_STRING: " << "reported warning";
LOG_STRING(ERROR, NULL) << "LOG_STRING: " << "reported error"; LOG_STRING(ERROR, nullptr) << "LOG_STRING: "
<< "reported error";
for (size_t i = 0; i < errors.size(); ++i) { for (auto& error : errors) {
LOG(INFO) << "Captured by LOG_STRING: " << errors[i]; LOG(INFO) << "Captured by LOG_STRING: " << error;
} }
} }
void TestLogToString() { void TestLogToString() {
string error; string error;
string* no_error = NULL; string* no_error = nullptr;
LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info"; LOG_TO_STRING(INFO, &error) << "LOG_TO_STRING: " << "collected info";
LOG(INFO) << "Captured by LOG_TO_STRING: " << error; LOG(INFO) << "Captured by LOG_TO_STRING: " << error;
@ -559,16 +558,17 @@ void TestLogToString() {
LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info"; LOG_TO_STRING(INFO, no_error) << "LOG_TO_STRING: " << "reported info";
LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning"; LOG_TO_STRING(WARNING, no_error) << "LOG_TO_STRING: " << "reported warning";
LOG_TO_STRING(ERROR, NULL) << "LOG_TO_STRING: " << "reported error"; LOG_TO_STRING(ERROR, nullptr) << "LOG_TO_STRING: "
<< "reported error";
} }
class TestLogSinkImpl : public LogSink { class TestLogSinkImpl : public LogSink {
public: public:
vector<string> errors; vector<string> errors;
virtual void send(LogSeverity severity, const char* /* full_filename */, void send(LogSeverity severity, const char* /* full_filename */,
const char* base_filename, int line, const char* base_filename, int line,
const LogMessageTime &logmsgtime, const LogMessageTime& logmsgtime, const char* message,
const char* message, size_t message_len) { size_t message_len) override {
errors.push_back( errors.push_back(
ToString(severity, base_filename, line, logmsgtime, message, message_len)); ToString(severity, base_filename, line, logmsgtime, message, message_len));
} }
@ -576,7 +576,7 @@ class TestLogSinkImpl : public LogSink {
void TestLogSink() { void TestLogSink() {
TestLogSinkImpl sink; TestLogSinkImpl sink;
LogSink *no_sink = NULL; LogSink* no_sink = nullptr;
LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info"; LOG_TO_SINK(&sink, INFO) << "LOG_TO_SINK: " << "collected info";
LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning"; LOG_TO_SINK(&sink, WARNING) << "LOG_TO_SINK: " << "collected warning";
@ -584,7 +584,8 @@ void TestLogSink() {
LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info"; LOG_TO_SINK(no_sink, INFO) << "LOG_TO_SINK: " << "reported info";
LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning"; LOG_TO_SINK(no_sink, WARNING) << "LOG_TO_SINK: " << "reported warning";
LOG_TO_SINK(NULL, ERROR) << "LOG_TO_SINK: " << "reported error"; LOG_TO_SINK(nullptr, ERROR) << "LOG_TO_SINK: "
<< "reported error";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO) LOG_TO_SINK_BUT_NOT_TO_LOGFILE(&sink, INFO)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info"; << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "collected info";
@ -597,13 +598,13 @@ void TestLogSink() {
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info"; << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed info";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING) LOG_TO_SINK_BUT_NOT_TO_LOGFILE(no_sink, WARNING)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning"; << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed warning";
LOG_TO_SINK_BUT_NOT_TO_LOGFILE(NULL, ERROR) LOG_TO_SINK_BUT_NOT_TO_LOGFILE(nullptr, ERROR)
<< "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: " << "thrashed error"; << "LOG_TO_SINK_BUT_NOT_TO_LOGFILE: "
<< "thrashed error";
LOG(INFO) << "Captured by LOG_TO_SINK:"; LOG(INFO) << "Captured by LOG_TO_SINK:";
for (size_t i = 0; i < sink.errors.size(); ++i) { for (auto& error : sink.errors) {
LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() LogMessage("foo", LogMessage::kNoLogPrefix, GLOG_INFO).stream() << error;
<< sink.errors[i];
} }
} }
@ -653,7 +654,7 @@ void TestDCHECK() {
DCHECK_GT(2, 1); DCHECK_GT(2, 1);
DCHECK_LT(1, 2); DCHECK_LT(1, 2);
int64* orig_ptr = new int64; auto* orig_ptr = new int64;
int64* ptr = DCHECK_NOTNULL(orig_ptr); int64* ptr = DCHECK_NOTNULL(orig_ptr);
CHECK_EQ(ptr, orig_ptr); CHECK_EQ(ptr, orig_ptr);
delete orig_ptr; delete orig_ptr;
@ -661,24 +662,24 @@ void TestDCHECK() {
void TestSTREQ() { void TestSTREQ() {
CHECK_STREQ("this", "this"); CHECK_STREQ("this", "this");
CHECK_STREQ(NULL, NULL); CHECK_STREQ(nullptr, nullptr);
CHECK_STRCASEEQ("this", "tHiS"); CHECK_STRCASEEQ("this", "tHiS");
CHECK_STRCASEEQ(NULL, NULL); CHECK_STRCASEEQ(nullptr, nullptr);
CHECK_STRNE("this", "tHiS"); CHECK_STRNE("this", "tHiS");
CHECK_STRNE("this", NULL); CHECK_STRNE("this", nullptr);
CHECK_STRCASENE("this", "that"); CHECK_STRCASENE("this", "that");
CHECK_STRCASENE(NULL, "that"); CHECK_STRCASENE(nullptr, "that");
CHECK_STREQ((string("a")+"b").c_str(), "ab"); CHECK_STREQ((string("a")+"b").c_str(), "ab");
CHECK_STREQ(string("test").c_str(), CHECK_STREQ(string("test").c_str(),
(string("te") + string("st")).c_str()); (string("te") + string("st")).c_str());
} }
TEST(DeathSTREQ, logging) { TEST(DeathSTREQ, logging) {
ASSERT_DEATH(CHECK_STREQ(NULL, "this"), ""); ASSERT_DEATH(CHECK_STREQ(nullptr, "this"), "");
ASSERT_DEATH(CHECK_STREQ("this", "siht"), ""); ASSERT_DEATH(CHECK_STREQ("this", "siht"), "");
ASSERT_DEATH(CHECK_STRCASEEQ(NULL, "siht"), ""); ASSERT_DEATH(CHECK_STRCASEEQ(nullptr, "siht"), "");
ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), ""); ASSERT_DEATH(CHECK_STRCASEEQ("this", "siht"), "");
ASSERT_DEATH(CHECK_STRNE(NULL, NULL), ""); ASSERT_DEATH(CHECK_STRNE(nullptr, nullptr), "");
ASSERT_DEATH(CHECK_STRNE("this", "this"), ""); ASSERT_DEATH(CHECK_STRNE("this", "this"), "");
ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), ""); ASSERT_DEATH(CHECK_STREQ((string("a")+"b").c_str(), "abc"), "");
} }
@ -695,7 +696,7 @@ TEST(CheckNOTNULL, Simple) {
} }
TEST(DeathCheckNN, Simple) { TEST(DeathCheckNN, Simple) {
ASSERT_DEATH(CHECK_NOTNULL(static_cast<void *>(NULL)), ""); ASSERT_DEATH(CHECK_NOTNULL(static_cast<void*>(nullptr)), "");
} }
// Get list of file names that match pattern // Get list of file names that match pattern
@ -703,7 +704,7 @@ static void GetFiles(const string& pattern, vector<string>* files) {
files->clear(); files->clear();
#if defined(HAVE_GLOB_H) #if defined(HAVE_GLOB_H)
glob_t g; glob_t g;
const int r = glob(pattern.c_str(), 0, NULL, &g); const int r = glob(pattern.c_str(), 0, nullptr, &g);
CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern; CHECK((r == 0) || (r == GLOB_NOMATCH)) << ": error matching " << pattern;
for (size_t i = 0; i < g.gl_pathc; i++) { for (size_t i = 0; i < g.gl_pathc; i++) {
files->push_back(string(g.gl_pathv[i])); files->push_back(string(g.gl_pathv[i]));
@ -735,8 +736,8 @@ static void GetFiles(const string& pattern, vector<string>* files) {
static void DeleteFiles(const string& pattern) { static void DeleteFiles(const string& pattern) {
vector<string> files; vector<string> files;
GetFiles(pattern, &files); GetFiles(pattern, &files);
for (size_t i = 0; i < files.size(); i++) { for (auto& file : files) {
CHECK(unlink(files[i].c_str()) == 0) << ": " << strerror(errno); CHECK(unlink(file.c_str()) == 0) << ": " << strerror(errno);
} }
} }
@ -747,13 +748,13 @@ static void CheckFile(const string& name, const string& expected_string, const b
CHECK_EQ(files.size(), 1UL); CHECK_EQ(files.size(), 1UL);
FILE* file = fopen(files[0].c_str(), "r"); FILE* file = fopen(files[0].c_str(), "r");
CHECK(file != NULL) << ": could not open " << files[0]; CHECK(file != nullptr) << ": could not open " << files[0];
char buf[1000]; char buf[1000];
while (fgets(buf, sizeof(buf), file) != NULL) { while (fgets(buf, sizeof(buf), file) != nullptr) {
char* first = strstr(buf, expected_string.c_str()); char* first = strstr(buf, expected_string.c_str());
//if first == NULL, not found. // if first == nullptr, not found.
//Terser than if (checkInFileOrNot && first != NULL || !check... // Terser than if (checkInFileOrNot && first != nullptr || !check...
if (checkInFileOrNot != (first == NULL)) { if (checkInFileOrNot != (first == nullptr)) {
fclose(file); fclose(file);
return; return;
} }
@ -824,7 +825,7 @@ static void TestTwoProcessesWrite() {
ShutdownGoogleLogging(); //for children proc ShutdownGoogleLogging(); //for children proc
exit(EXIT_SUCCESS); exit(EXIT_SUCCESS);
} else if (pid > 0) { } else if (pid > 0) {
wait(NULL); wait(nullptr);
} }
FLAGS_timestamp_in_logfile_name=true; FLAGS_timestamp_in_logfile_name=true;
@ -871,7 +872,7 @@ static void TestExtension() {
vector<string> filenames; vector<string> filenames;
GetFiles(dest + "*", &filenames); GetFiles(dest + "*", &filenames);
CHECK_EQ(filenames.size(), 1UL); CHECK_EQ(filenames.size(), 1UL);
CHECK(strstr(filenames[0].c_str(), "specialextension") != NULL); CHECK(strstr(filenames[0].c_str(), "specialextension") != nullptr);
// Release file handle for the destination file to unlock the file in Windows. // Release file handle for the destination file to unlock the file in Windows.
LogToStderr(); LogToStderr();
@ -884,18 +885,16 @@ struct MyLogger : public base::Logger {
explicit MyLogger(bool* set_on_destruction) explicit MyLogger(bool* set_on_destruction)
: set_on_destruction_(set_on_destruction) {} : set_on_destruction_(set_on_destruction) {}
~MyLogger() { *set_on_destruction_ = true; } ~MyLogger() override { *set_on_destruction_ = true; }
virtual void Write(bool /* should_flush */, void Write(bool /* should_flush */, time_t /* timestamp */,
time_t /* timestamp */, const char* message, size_t length) override {
const char* message,
size_t length) {
data.append(message, length); data.append(message, length);
} }
virtual void Flush() { } void Flush() override {}
virtual uint32 LogSize() { return data.length(); } uint32 LogSize() override { return data.length(); }
private: private:
bool* set_on_destruction_; bool* set_on_destruction_;
@ -905,11 +904,11 @@ static void TestWrapper() {
fprintf(stderr, "==== Test log wrapper\n"); fprintf(stderr, "==== Test log wrapper\n");
bool custom_logger_deleted = false; bool custom_logger_deleted = false;
MyLogger* my_logger = new MyLogger(&custom_logger_deleted); auto* my_logger = new MyLogger(&custom_logger_deleted);
base::Logger* old_logger = base::GetLogger(GLOG_INFO); base::Logger* old_logger = base::GetLogger(GLOG_INFO);
base::SetLogger(GLOG_INFO, my_logger); base::SetLogger(GLOG_INFO, my_logger);
LOG(INFO) << "Send to wrapped logger"; LOG(INFO) << "Send to wrapped logger";
CHECK(strstr(my_logger->data.c_str(), "Send to wrapped logger") != NULL); CHECK(strstr(my_logger->data.c_str(), "Send to wrapped logger") != nullptr);
FlushLogFiles(GLOG_INFO); FlushLogFiles(GLOG_INFO);
EXPECT_FALSE(custom_logger_deleted); EXPECT_FALSE(custom_logger_deleted);
@ -1022,17 +1021,14 @@ struct RecordDeletionLogger : public base::Logger {
{ {
*set_on_destruction_ = false; *set_on_destruction_ = false;
} }
virtual ~RecordDeletionLogger() { ~RecordDeletionLogger() override { *set_on_destruction_ = true; }
*set_on_destruction_ = true; void Write(bool force_flush, time_t timestamp, const char* message,
} size_t length) override {
virtual void Write(bool force_flush,
time_t timestamp,
const char* message,
size_t length) {
wrapped_logger_->Write(force_flush, timestamp, message, length); wrapped_logger_->Write(force_flush, timestamp, message, length);
} }
virtual void Flush() { wrapped_logger_->Flush(); } void Flush() override { wrapped_logger_->Flush(); }
virtual uint32 LogSize() { return wrapped_logger_->LogSize(); } uint32 LogSize() override { return wrapped_logger_->LogSize(); }
private: private:
bool* set_on_destruction_; bool* set_on_destruction_;
base::Logger* wrapped_logger_; base::Logger* wrapped_logger_;
@ -1054,20 +1050,19 @@ namespace LogTimes {
// between total running time of 100ms and the period of 10ms. The period is // between total running time of 100ms and the period of 10ms. The period is
// large enough such that any CPU and OS scheduling variation shouldn't affect // large enough such that any CPU and OS scheduling variation shouldn't affect
// the results from the ideal case by more than 5% (500us or 0.5ms) // the results from the ideal case by more than 5% (500us or 0.5ms)
GLOG_CONSTEXPR int64_t LOG_PERIOD_NS = 10000000; // 10ms constexpr int64_t LOG_PERIOD_NS = 10000000; // 10ms
GLOG_CONSTEXPR int64_t LOG_PERIOD_TOL_NS = 500000; // 500us constexpr int64_t LOG_PERIOD_TOL_NS = 500000; // 500us
// Set an upper limit for the number of times the stream operator can be // Set an upper limit for the number of times the stream operator can be
// called. Make sure not to exceed this number of times the stream operator is // called. Make sure not to exceed this number of times the stream operator is
// called, since it is also the array size and will be indexed by the stream // called, since it is also the array size and will be indexed by the stream
// operator. // operator.
GLOG_CONSTEXPR size_t MAX_CALLS = 10; constexpr size_t MAX_CALLS = 10;
} // namespace LogTimes } // namespace LogTimes
#if defined(HAVE_CXX11_CHRONO) && __cplusplus >= 201103L
struct LogTimeRecorder { struct LogTimeRecorder {
LogTimeRecorder() : m_streamTimes(0) {} LogTimeRecorder() = default;
size_t m_streamTimes; size_t m_streamTimes{0};
std::chrono::steady_clock::time_point m_callTimes[LogTimes::MAX_CALLS]; std::chrono::steady_clock::time_point m_callTimes[LogTimes::MAX_CALLS];
}; };
// The stream operator is called by LOG_EVERY_T every time a logging event // The stream operator is called by LOG_EVERY_T every time a logging event
@ -1083,45 +1078,13 @@ int64 elapsedTime_ns(const std::chrono::steady_clock::time_point& begin,
return std::chrono::duration_cast<std::chrono::nanoseconds>((end - begin)) return std::chrono::duration_cast<std::chrono::nanoseconds>((end - begin))
.count(); .count();
} }
#elif defined(GLOG_OS_WINDOWS)
struct LogTimeRecorder {
LogTimeRecorder() : m_streamTimes(0) {}
size_t m_streamTimes;
LARGE_INTEGER m_callTimes[LogTimes::MAX_CALLS];
};
std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
QueryPerformanceCounter(&t.m_callTimes[t.m_streamTimes++]);
return stream;
}
// get elapsed time in nanoseconds
int64 elapsedTime_ns(const LARGE_INTEGER& begin, const LARGE_INTEGER& end) {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return (end.QuadPart - begin.QuadPart) * LONGLONG(1000000000) / freq.QuadPart;
}
#else
struct LogTimeRecorder {
LogTimeRecorder() : m_streamTimes(0) {}
size_t m_streamTimes;
timespec m_callTimes[LogTimes::MAX_CALLS];
};
std::ostream& operator<<(std::ostream& stream, LogTimeRecorder& t) {
clock_gettime(CLOCK_MONOTONIC, &t.m_callTimes[t.m_streamTimes++]);
return stream;
}
// get elapsed time in nanoseconds
int64 elapsedTime_ns(const timespec& begin, const timespec& end) {
return (end.tv_sec - begin.tv_sec) * 1000000000 +
(end.tv_nsec - begin.tv_nsec);
}
#endif
static void TestLogPeriodically() { static void TestLogPeriodically() {
fprintf(stderr, "==== Test log periodically\n"); fprintf(stderr, "==== Test log periodically\n");
LogTimeRecorder timeLogger; LogTimeRecorder timeLogger;
GLOG_CONSTEXPR double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9; constexpr double LOG_PERIOD_SEC = LogTimes::LOG_PERIOD_NS * 1e-9;
while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) { while (timeLogger.m_streamTimes < LogTimes::MAX_CALLS) {
LOG_EVERY_T(INFO, LOG_PERIOD_SEC) LOG_EVERY_T(INFO, LOG_PERIOD_SEC)
@ -1136,8 +1099,7 @@ static void TestLogPeriodically() {
timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]); timeLogger.m_callTimes[i - 1], timeLogger.m_callTimes[i]);
} }
for (size_t idx = 0; idx < LogTimes::MAX_CALLS - 1; ++idx) { for (long time_ns : nsBetweenCalls) {
int64 time_ns = nsBetweenCalls[idx];
EXPECT_NEAR(time_ns, LogTimes::LOG_PERIOD_NS, LogTimes::LOG_PERIOD_TOL_NS); EXPECT_NEAR(time_ns, LogTimes::LOG_PERIOD_NS, LogTimes::LOG_PERIOD_TOL_NS);
} }
} }
@ -1188,8 +1150,7 @@ static vector<string> global_messages;
// It's free to use LOG() itself. // It's free to use LOG() itself.
class TestLogSinkWriter : public Thread { class TestLogSinkWriter : public Thread {
public: public:
TestLogSinkWriter() {
TestLogSinkWriter() : should_exit_(false) {
SetJoinable(true); SetJoinable(true);
Start(); Start();
} }
@ -1231,8 +1192,8 @@ class TestLogSinkWriter : public Thread {
bool HaveWork() { return !messages_.empty() || should_exit_; } bool HaveWork() { return !messages_.empty() || should_exit_; }
// Thread body; CAN use LOG() here! // Thread body; CAN use LOG() here!
virtual void Run() { void Run() override {
while (1) { while (true) {
mutex_.Lock(); mutex_.Lock();
while (!HaveWork()) { while (!HaveWork()) {
mutex_.Unlock(); mutex_.Unlock();
@ -1269,7 +1230,7 @@ class TestLogSinkWriter : public Thread {
// data --------------- // data ---------------
Mutex mutex_; Mutex mutex_;
bool should_exit_; bool should_exit_{false};
queue<string> messages_; // messages to be logged queue<string> messages_; // messages to be logged
}; };
@ -1283,7 +1244,7 @@ class TestWaitingLogSink : public LogSink {
tid_ = pthread_self(); // for thread-specific behavior tid_ = pthread_self(); // for thread-specific behavior
AddLogSink(this); AddLogSink(this);
} }
~TestWaitingLogSink() { ~TestWaitingLogSink() override {
RemoveLogSink(this); RemoveLogSink(this);
writer_.Stop(); writer_.Stop();
writer_.Join(); writer_.Join();
@ -1291,10 +1252,10 @@ class TestWaitingLogSink : public LogSink {
// (re)define LogSink interface // (re)define LogSink interface
virtual void send(LogSeverity severity, const char* /* full_filename */, void send(LogSeverity severity, const char* /* full_filename */,
const char* base_filename, int line, const char* base_filename, int line,
const LogMessageTime &logmsgtime, const LogMessageTime& logmsgtime, const char* message,
const char* message, size_t message_len) { size_t message_len) override {
// Push it to Writer thread if we are the original logging thread. // Push it to Writer thread if we are the original logging thread.
// Note: Something like ThreadLocalLogSink is a better choice // Note: Something like ThreadLocalLogSink is a better choice
// to do thread-specific LogSink logic for real. // to do thread-specific LogSink logic for real.
@ -1304,7 +1265,7 @@ class TestWaitingLogSink : public LogSink {
} }
} }
virtual void WaitTillSent() { void WaitTillSent() override {
// Wait for Writer thread if we are the original logging thread. // Wait for Writer thread if we are the original logging thread.
if (pthread_equal(tid_, pthread_self())) writer_.Wait(); if (pthread_equal(tid_, pthread_self())) writer_.Wait();
} }
@ -1331,8 +1292,8 @@ static void TestLogSinkWaitTillSent() {
LOG(WARNING) << "Message 3"; LOG(WARNING) << "Message 3";
SleepForMilliseconds(60); SleepForMilliseconds(60);
} }
for (size_t i = 0; i < global_messages.size(); ++i) { for (auto& global_message : global_messages) {
LOG(INFO) << "Sink capture: " << global_messages[i]; LOG(INFO) << "Sink capture: " << global_message;
} }
CHECK_EQ(global_messages.size(), 3UL); CHECK_EQ(global_messages.size(), 3UL);
} }
@ -1342,11 +1303,11 @@ TEST(Strerror, logging) {
char *msg = strdup(strerror(errcode)); char *msg = strdup(strerror(errcode));
const size_t buf_size = strlen(msg) + 1; const size_t buf_size = strlen(msg) + 1;
char *buf = new char[buf_size]; char *buf = new char[buf_size];
CHECK_EQ(posix_strerror_r(errcode, NULL, 0), -1); CHECK_EQ(posix_strerror_r(errcode, nullptr, 0), -1);
buf[0] = 'A'; buf[0] = 'A';
CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1); CHECK_EQ(posix_strerror_r(errcode, buf, 0), -1);
CHECK_EQ(buf[0], 'A'); CHECK_EQ(buf[0], 'A');
CHECK_EQ(posix_strerror_r(errcode, NULL, buf_size), -1); CHECK_EQ(posix_strerror_r(errcode, nullptr, buf_size), -1);
#if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD) #if defined(GLOG_OS_MACOSX) || defined(GLOG_OS_FREEBSD) || defined(GLOG_OS_OPENBSD)
// MacOSX or FreeBSD considers this case is an error since there is // MacOSX or FreeBSD considers this case is an error since there is
// no enough space. // no enough space.

View File

@ -72,7 +72,7 @@ class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
ScopedMockLog() { AddLogSink(this); } ScopedMockLog() { AddLogSink(this); }
// When the object is destructed, it stops intercepting logs. // When the object is destructed, it stops intercepting logs.
~ScopedMockLog() { RemoveLogSink(this); } ~ScopedMockLog() override { RemoveLogSink(this); }
// Implements the mock method: // Implements the mock method:
// //
@ -113,11 +113,10 @@ class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
// be running simultaneously, we ensure thread-safety of the exchange between // be running simultaneously, we ensure thread-safety of the exchange between
// send() and WaitTillSent(), and that for each message, LOG(), send(), // send() and WaitTillSent(), and that for each message, LOG(), send(),
// WaitTillSent() and Log() are executed in the same thread. // WaitTillSent() and Log() are executed in the same thread.
virtual void send(GOOGLE_NAMESPACE::LogSeverity severity, void send(GOOGLE_NAMESPACE::LogSeverity severity, const char* full_filename,
const char* full_filename, const char* /*base_filename*/, int /*line*/,
const char* /*base_filename*/, int /*line*/, const LogMessageTime& /*logmsgtime*/, const char* message,
const LogMessageTime & /*logmsgtime*/, size_t message_len) override {
const char* message, size_t message_len) {
// We are only interested in the log severity, full file name, and // We are only interested in the log severity, full file name, and
// log message. // log message.
message_info_.severity = severity; message_info_.severity = severity;
@ -132,7 +131,7 @@ class ScopedMockLog : public GOOGLE_NAMESPACE::LogSink {
// //
// LOG(), send(), WaitTillSent() and Log() will occur in the same thread for // LOG(), send(), WaitTillSent() and Log() will occur in the same thread for
// a given log message. // a given log message.
virtual void WaitTillSent() { void WaitTillSent() override {
// First, and very importantly, we save a copy of the message being // First, and very importantly, we save a copy of the message being
// processed before calling Log(), since Log() may indirectly call send() // processed before calling Log(), since Log() may indirectly call send()
// and WaitTillSent() in the same thread again. // and WaitTillSent() in the same thread again.

View File

@ -31,11 +31,11 @@
// //
// logging_unittest.cc covers the functionality herein // logging_unittest.cc covers the functionality herein
#include "utilities.h"
#include <stdarg.h>
#include <cstdio>
#include <cerrno> #include <cerrno>
#include <cstdarg>
#include <cstdio>
#include "utilities.h"
#ifdef HAVE_UNISTD_H #ifdef HAVE_UNISTD_H
# include <unistd.h> // for close() and write() # include <unistd.h> // for close() and write()
#endif #endif

View File

@ -72,17 +72,17 @@ const struct {
static bool kFailureSignalHandlerInstalled = false; static bool kFailureSignalHandlerInstalled = false;
#if !defined(GLOG_OS_WINDOWS) #if !defined(GLOG_OS_WINDOWS)
// Returns the program counter from signal context, NULL if unknown. // Returns the program counter from signal context, nullptr if unknown.
void* GetPC(void* ucontext_in_void) { void* GetPC(void* ucontext_in_void) {
#if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT) #if (defined(HAVE_UCONTEXT_H) || defined(HAVE_SYS_UCONTEXT_H)) && defined(PC_FROM_UCONTEXT)
if (ucontext_in_void != NULL) { if (ucontext_in_void != nullptr) {
ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void); ucontext_t *context = reinterpret_cast<ucontext_t *>(ucontext_in_void);
return (void*)context->PC_FROM_UCONTEXT; return (void*)context->PC_FROM_UCONTEXT;
} }
#else #else
(void)ucontext_in_void; (void)ucontext_in_void;
#endif #endif
return NULL; return nullptr;
} }
#endif #endif
@ -161,7 +161,7 @@ void (*g_failure_writer)(const char* data, size_t size) = WriteToStderr;
// Dumps time information. We don't dump human-readable time information // Dumps time information. We don't dump human-readable time information
// as localtime() is not guaranteed to be async signal safe. // as localtime() is not guaranteed to be async signal safe.
void DumpTimeInfo() { void DumpTimeInfo() {
time_t time_in_sec = time(NULL); time_t time_in_sec = time(nullptr);
char buf[256]; // Big enough for time info. char buf[256]; // Big enough for time info.
MinimalFormatter formatter(buf, sizeof(buf)); MinimalFormatter formatter(buf, sizeof(buf));
formatter.AppendString("*** Aborted at "); formatter.AppendString("*** Aborted at ");
@ -179,10 +179,10 @@ void DumpTimeInfo() {
// Dumps information about the signal to STDERR. // Dumps information about the signal to STDERR.
void DumpSignalInfo(int signal_number, siginfo_t *siginfo) { void DumpSignalInfo(int signal_number, siginfo_t *siginfo) {
// Get the signal name. // Get the signal name.
const char* signal_name = NULL; const char* signal_name = nullptr;
for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { for (auto kFailureSignal : kFailureSignals) {
if (signal_number == kFailureSignals[i].number) { if (signal_number == kFailureSignal.number) {
signal_name = kFailureSignals[i].name; signal_name = kFailureSignal.name;
} }
} }
@ -256,7 +256,7 @@ void InvokeDefaultSignalHandler(int signal_number) {
memset(&sig_action, 0, sizeof(sig_action)); memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask); sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL; sig_action.sa_handler = SIG_DFL;
sigaction(signal_number, &sig_action, NULL); sigaction(signal_number, &sig_action, nullptr);
kill(getpid(), signal_number); kill(getpid(), signal_number);
#elif defined(GLOG_OS_WINDOWS) #elif defined(GLOG_OS_WINDOWS)
signal(signal_number, SIG_DFL); signal(signal_number, SIG_DFL);
@ -268,7 +268,7 @@ void InvokeDefaultSignalHandler(int signal_number) {
// dumping stuff while another thread is doing it. Our policy is to let // dumping stuff while another thread is doing it. Our policy is to let
// the first thread dump stuff and let other threads wait. // the first thread dump stuff and let other threads wait.
// See also comments in FailureSignalHandler(). // See also comments in FailureSignalHandler().
static pthread_t* g_entered_thread_id_pointer = NULL; static pthread_t* g_entered_thread_id_pointer = nullptr;
// Dumps signal and stack frame information, and invokes the default // Dumps signal and stack frame information, and invokes the default
// signal handler once our job is done. // signal handler once our job is done.
@ -291,13 +291,12 @@ void FailureSignalHandler(int signal_number,
// if pthread_self() is guaranteed to return non-zero value for thread // if pthread_self() is guaranteed to return non-zero value for thread
// ids, but there is no such guarantee. We need to distinguish if the // ids, but there is no such guarantee. We need to distinguish if the
// old value (value returned from __sync_val_compare_and_swap) is // old value (value returned from __sync_val_compare_and_swap) is
// different from the original value (in this case NULL). // different from the original value (in this case nullptr).
pthread_t* old_thread_id_pointer = pthread_t* old_thread_id_pointer =
glog_internal_namespace_::sync_val_compare_and_swap( glog_internal_namespace_::sync_val_compare_and_swap(
&g_entered_thread_id_pointer, &g_entered_thread_id_pointer, static_cast<pthread_t*>(nullptr),
static_cast<pthread_t*>(NULL),
&my_thread_id); &my_thread_id);
if (old_thread_id_pointer != NULL) { if (old_thread_id_pointer != nullptr) {
// We've already entered the signal handler. What should we do? // We've already entered the signal handler. What should we do?
if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) { if (pthread_equal(my_thread_id, *g_entered_thread_id_pointer)) {
// It looks the current thread is reentering the signal handler. // It looks the current thread is reentering the signal handler.
@ -370,7 +369,7 @@ bool IsFailureSignalHandlerInstalled() {
struct sigaction sig_action; struct sigaction sig_action;
memset(&sig_action, 0, sizeof(sig_action)); memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask); sigemptyset(&sig_action.sa_mask);
sigaction(SIGABRT, NULL, &sig_action); sigaction(SIGABRT, nullptr, &sig_action);
if (sig_action.sa_sigaction == &FailureSignalHandler) { if (sig_action.sa_sigaction == &FailureSignalHandler) {
return true; return true;
} }
@ -391,8 +390,8 @@ void InstallFailureSignalHandler() {
sig_action.sa_flags |= SA_SIGINFO; sig_action.sa_flags |= SA_SIGINFO;
sig_action.sa_sigaction = &FailureSignalHandler; sig_action.sa_sigaction = &FailureSignalHandler;
for (size_t i = 0; i < ARRAYSIZE(kFailureSignals); ++i) { for (auto kFailureSignal : kFailureSignals) {
CHECK_ERR(sigaction(kFailureSignals[i].number, &sig_action, NULL)); CHECK_ERR(sigaction(kFailureSignal.number, &sig_action, nullptr));
} }
kFailureSignalHandlerInstalled = true; kFailureSignalHandlerInstalled = true;
#elif defined(GLOG_OS_WINDOWS) #elif defined(GLOG_OS_WINDOWS)

View File

@ -62,7 +62,7 @@ static void* DieInThread(void*) {
volatile int a = 0; volatile int a = 0;
volatile int b = 1 / a; volatile int b = 1 / a;
fprintf(stderr, "We should have died: b=%d\n", b); fprintf(stderr, "We should have died: b=%d\n", b);
return NULL; return nullptr;
} }
static void WriteToStdout(const char* data, size_t size) { static void WriteToStdout(const char* data, size_t size) {
@ -92,8 +92,8 @@ int main(int argc, char **argv) {
} else if (command == "die_in_thread") { } else if (command == "die_in_thread") {
#if defined(HAVE_PTHREAD) #if defined(HAVE_PTHREAD)
pthread_t thread; pthread_t thread;
pthread_create(&thread, NULL, &DieInThread, NULL); pthread_create(&thread, nullptr, &DieInThread, nullptr);
pthread_join(thread, NULL); pthread_join(thread, nullptr);
#else #else
fprintf(stderr, "no pthread\n"); fprintf(stderr, "no pthread\n");
return 1; return 1;

View File

@ -53,7 +53,7 @@ _START_GOOGLE_NAMESPACE_
// result[1] main // result[1] main
// .... ... // .... ...
// //
// "result" must not be NULL. // "result" must not be nullptr.
GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count); GLOG_EXPORT int GetStackTrace(void** result, int max_depth, int skip_count);
_END_GOOGLE_NAMESPACE_ _END_GOOGLE_NAMESPACE_

View File

@ -32,7 +32,9 @@
// Note: The glibc implementation may cause a call to malloc. // Note: The glibc implementation may cause a call to malloc.
// This can cause a deadlock in HeapProfiler. // This can cause a deadlock in HeapProfiler.
#include <execinfo.h> #include <execinfo.h>
#include <string.h>
#include <cstring>
#include "stacktrace.h" #include "stacktrace.h"
_START_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_

View File

@ -35,14 +35,15 @@
// http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK // http://www.linux-foundation.org/spec/ELF/ppc64/PPC-elf64abi-1.9.html#STACK
// Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882 // Linux has similar code: http://patchwork.ozlabs.org/linuxppc/patch?id=8882
#include <cstdint> // for uintptr_t
#include <cstdio> #include <cstdio>
#include <stdint.h> // for uintptr_t
#include "stacktrace.h" #include "stacktrace.h"
_START_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_
// Given a pointer to a stack frame, locate and return the calling // Given a pointer to a stack frame, locate and return the calling
// stackframe, or return NULL if no stackframe can be found. Perform sanity // stackframe, or return nullptr if no stackframe can be found. Perform sanity
// checks (the strictness of which is controlled by the boolean parameter // checks (the strictness of which is controlled by the boolean parameter
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. // "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
template<bool STRICT_UNWINDING> template<bool STRICT_UNWINDING>
@ -54,18 +55,20 @@ static void **NextStackFrame(void **old_sp) {
if (STRICT_UNWINDING) { if (STRICT_UNWINDING) {
// With the stack growing downwards, older stack frame must be // With the stack growing downwards, older stack frame must be
// at a greater address that the current one. // at a greater address that the current one.
if (new_sp <= old_sp) return NULL; if (new_sp <= old_sp) return nullptr;
// Assume stack frames larger than 100,000 bytes are bogus. // Assume stack frames larger than 100,000 bytes are bogus.
if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return NULL; if ((uintptr_t)new_sp - (uintptr_t)old_sp > 100000) return nullptr;
} else { } else {
// In the non-strict mode, allow discontiguous stack frames. // In the non-strict mode, allow discontiguous stack frames.
// (alternate-signal-stacks for example). // (alternate-signal-stacks for example).
if (new_sp == old_sp) return NULL; if (new_sp == old_sp) return nullptr;
// And allow frames upto about 1MB. // And allow frames upto about 1MB.
if ((new_sp > old_sp) if ((new_sp > old_sp) &&
&& ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) return NULL; ((uintptr_t)new_sp - (uintptr_t)old_sp > 1000000)) {
return nullptr;
}
} }
if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return NULL; if ((uintptr_t)new_sp & (sizeof(void *) - 1)) return nullptr;
return new_sp; return new_sp;
} }

View File

@ -117,7 +117,7 @@ static void CheckRetAddrIsInFunction(void *ret_addr, const AddressRange &range)
#endif #endif
void ATTRIBUTE_NOINLINE CheckStackTrace(int); void ATTRIBUTE_NOINLINE CheckStackTrace(int);
static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) { static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf() {
const int STACK_LEN = 10; const int STACK_LEN = 10;
void *stack[STACK_LEN]; void *stack[STACK_LEN];
int size; int size;
@ -130,7 +130,7 @@ static void ATTRIBUTE_NOINLINE CheckStackTraceLeaf(void) {
CHECK_GE(size, 1); CHECK_GE(size, 1);
CHECK_LE(size, STACK_LEN); CHECK_LE(size, STACK_LEN);
if (1) { if (true) {
#ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS #ifdef HAVE_EXECINFO_BACKTRACE_SYMBOLS
char **strings = backtrace_symbols(stack, size); char **strings = backtrace_symbols(stack, size);
printf("Obtained %d stack frames.\n", size); printf("Obtained %d stack frames.\n", size);

View File

@ -31,8 +31,9 @@
// //
// Produce stack trace using libgcc // Produce stack trace using libgcc
#include <cstdlib> // for NULL #include <unwind.h> // ABI defined unwinder
#include <unwind.h> // ABI defined unwinder
#include <cstdlib> // for nullptr
#include "stacktrace.h" #include "stacktrace.h"
@ -59,7 +60,7 @@ class StackTraceInit {
public: public:
StackTraceInit() { StackTraceInit() {
// Extra call to force initialization // Extra call to force initialization
_Unwind_Backtrace(nop_backtrace, NULL); _Unwind_Backtrace(nop_backtrace, nullptr);
ready_to_run = true; ready_to_run = true;
} }
}; };
@ -67,13 +68,13 @@ class StackTraceInit {
static StackTraceInit module_initializer; // Force initialization static StackTraceInit module_initializer; // Force initialization
static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) { static _Unwind_Reason_Code GetOneFrame(struct _Unwind_Context *uc, void *opq) {
trace_arg_t *targ = static_cast<trace_arg_t *>(opq); auto *targ = static_cast<trace_arg_t *>(opq);
if (targ->skip_count > 0) { if (targ->skip_count > 0) {
targ->skip_count--; targ->skip_count--;
} else { } else {
targ->result[targ->count++] = reinterpret_cast<void *>(_Unwind_GetIP(uc)); targ->result[targ->count++] = reinterpret_cast<void *>(_Unwind_GetIP(uc));
} }
if (targ->count == targ->max_depth) { if (targ->count == targ->max_depth) {
return _URC_END_OF_STACK; return _URC_END_OF_STACK;

View File

@ -44,7 +44,8 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
} }
skip_count++; // we want to skip the current frame as well skip_count++; // we want to skip the current frame as well
// This API is thread-safe (moreover it walks only the current thread). // This API is thread-safe (moreover it walks only the current thread).
return CaptureStackBackTrace(static_cast<DWORD>(skip_count), static_cast<DWORD>(max_depth), result, NULL); return CaptureStackBackTrace(static_cast<DWORD>(skip_count),
static_cast<DWORD>(max_depth), result, nullptr);
} }
_END_GOOGLE_NAMESPACE_ _END_GOOGLE_NAMESPACE_

View File

@ -29,7 +29,7 @@
// //
// Produce stack trace // Produce stack trace
#include <stdint.h> // for uintptr_t #include <cstdint> // for uintptr_t
#include "utilities.h" // for OS_* macros #include "utilities.h" // for OS_* macros
@ -38,13 +38,14 @@
#include <sys/mman.h> #include <sys/mman.h>
#endif #endif
#include <cstdio> // for NULL #include <cstdio> // for nullptr
#include "stacktrace.h" #include "stacktrace.h"
_START_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_
// Given a pointer to a stack frame, locate and return the calling // Given a pointer to a stack frame, locate and return the calling
// stackframe, or return NULL if no stackframe can be found. Perform sanity // stackframe, or return nullptr if no stackframe can be found. Perform sanity
// checks (the strictness of which is controlled by the boolean parameter // checks (the strictness of which is controlled by the boolean parameter
// "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned. // "STRICT_UNWINDING") to reduce the chance that a bad pointer is returned.
template<bool STRICT_UNWINDING> template<bool STRICT_UNWINDING>
@ -56,28 +57,32 @@ static void **NextStackFrame(void **old_sp) {
if (STRICT_UNWINDING) { if (STRICT_UNWINDING) {
// With the stack growing downwards, older stack frame must be // With the stack growing downwards, older stack frame must be
// at a greater address that the current one. // at a greater address that the current one.
if (new_sp <= old_sp) return NULL; if (new_sp <= old_sp) return nullptr;
// Assume stack frames larger than 100,000 bytes are bogus. // Assume stack frames larger than 100,000 bytes are bogus.
if (reinterpret_cast<uintptr_t>(new_sp) - if (reinterpret_cast<uintptr_t>(new_sp) -
reinterpret_cast<uintptr_t>(old_sp) > reinterpret_cast<uintptr_t>(old_sp) >
100000) 100000) {
return NULL; return nullptr;
}
} else { } else {
// In the non-strict mode, allow discontiguous stack frames. // In the non-strict mode, allow discontiguous stack frames.
// (alternate-signal-stacks for example). // (alternate-signal-stacks for example).
if (new_sp == old_sp) return NULL; if (new_sp == old_sp) return nullptr;
// And allow frames upto about 1MB. // And allow frames upto about 1MB.
if ((new_sp > old_sp) && (reinterpret_cast<uintptr_t>(new_sp) - if ((new_sp > old_sp) && (reinterpret_cast<uintptr_t>(new_sp) -
reinterpret_cast<uintptr_t>(old_sp) > reinterpret_cast<uintptr_t>(old_sp) >
1000000)) 1000000)) {
return NULL; return nullptr;
}
}
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void *) - 1)) {
return nullptr;
} }
if (reinterpret_cast<uintptr_t>(new_sp) & (sizeof(void *) - 1)) return NULL;
#ifdef __i386__ #ifdef __i386__
// On 64-bit machines, the stack pointer can be very close to // On 64-bit machines, the stack pointer can be very close to
// 0xffffffff, so we explicitly check for a pointer into the // 0xffffffff, so we explicitly check for a pointer into the
// last two pages in the address space // last two pages in the address space
if ((uintptr_t)new_sp >= 0xffffe000) return NULL; if ((uintptr_t)new_sp >= 0xffffe000) return nullptr;
#endif #endif
#if !defined(GLOG_OS_WINDOWS) #if !defined(GLOG_OS_WINDOWS)
if (!STRICT_UNWINDING) { if (!STRICT_UNWINDING) {
@ -91,7 +96,7 @@ static void **NextStackFrame(void **old_sp) {
reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) & reinterpret_cast<void *>(reinterpret_cast<uintptr_t>(new_sp) &
static_cast<uintptr_t>(~(page_size - 1))); static_cast<uintptr_t>(~(page_size - 1)));
if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) { if (msync(new_sp_aligned, static_cast<size_t>(page_size), MS_ASYNC) == -1) {
return NULL; return nullptr;
} }
} }
#endif #endif
@ -135,7 +140,7 @@ int GetStackTrace(void** result, int max_depth, int skip_count) {
int n = 0; int n = 0;
while (sp && n < max_depth) { while (sp && n < max_depth) {
if (*(sp + 1) == NULL) { if (*(sp + 1) == nullptr) {
// In 64-bit code, we often see a frame that // In 64-bit code, we often see a frame that
// points to itself and has a return address of 0. // points to itself and has a return address of 0.
break; break;

View File

@ -27,9 +27,8 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "config.h" #include <glog/logging.h>
#include <glog/stl_logging.h>
#ifdef HAVE_USING_OPERATOR
#include <functional> #include <functional>
#include <iostream> #include <iostream>
@ -38,34 +37,10 @@
#include <string> #include <string>
#include <vector> #include <vector>
#ifdef __GNUC__ #include "config.h"
// C++0x isn't enabled by default in GCC and libc++ does not have
// non-standard ext/* and tr1/unordered_*.
# if defined(_LIBCPP_VERSION)
# ifndef GLOG_STL_LOGGING_FOR_UNORDERED
# define GLOG_STL_LOGGING_FOR_UNORDERED
# endif
# else
# ifndef GLOG_STL_LOGGING_FOR_EXT_HASH
# define GLOG_STL_LOGGING_FOR_EXT_HASH
# endif
# ifndef GLOG_STL_LOGGING_FOR_EXT_SLIST
# define GLOG_STL_LOGGING_FOR_EXT_SLIST
# endif
# ifndef GLOG_STL_LOGGING_FOR_TR1_UNORDERED
# define GLOG_STL_LOGGING_FOR_TR1_UNORDERED
# endif
# endif
#endif
#include <glog/logging.h>
#include <glog/stl_logging.h>
#include "googletest.h" #include "googletest.h"
using namespace std; using namespace std;
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
using namespace __gnu_cxx;
#endif
struct user_hash { struct user_hash {
size_t operator()(int x) const { return static_cast<size_t>(x); } size_t operator()(int x) const { return static_cast<size_t>(x); }
@ -98,42 +73,6 @@ static void TestSTLLogging() {
CHECK_EQ(m, copied_m); // This must compile. CHECK_EQ(m, copied_m); // This must compile.
} }
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
{
// Test a hashed simple associative container.
hash_set<int> hs;
hs.insert(10);
hs.insert(20);
hs.insert(30);
ostringstream ss;
ss << hs;
EXPECT_EQ(ss.str().size(), 8);
EXPECT_TRUE(ss.str().find("10") != string::npos);
EXPECT_TRUE(ss.str().find("20") != string::npos);
EXPECT_TRUE(ss.str().find("30") != string::npos);
hash_set<int> copied_hs(hs);
CHECK_EQ(hs, copied_hs); // This must compile.
}
#endif
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
{
// Test a hashed pair associative container.
hash_map<int, string> hm;
hm[10] = "ten";
hm[20] = "twenty";
hm[30] = "thirty";
ostringstream ss;
ss << hm;
EXPECT_EQ(ss.str().size(), 35);
EXPECT_TRUE(ss.str().find("(10, ten)") != string::npos);
EXPECT_TRUE(ss.str().find("(20, twenty)") != string::npos);
EXPECT_TRUE(ss.str().find("(30, thirty)") != string::npos);
hash_map<int, string> copied_hm(hm);
CHECK_EQ(hm, copied_hm); // this must compile
}
#endif
{ {
// Test a long sequence. // Test a long sequence.
vector<int> v; vector<int> v;
@ -156,35 +95,16 @@ static void TestSTLLogging() {
{ {
// Test a sorted pair associative container. // Test a sorted pair associative container.
// Use a non-default comparison functor. // Use a non-default comparison functor.
map< int, string, greater<int> > m; map<int, string, greater<> > m;
m[20] = "twenty"; m[20] = "twenty";
m[10] = "ten"; m[10] = "ten";
m[30] = "thirty"; m[30] = "thirty";
ostringstream ss; ostringstream ss;
ss << m; ss << m;
EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)"); EXPECT_EQ(ss.str(), "(30, thirty) (20, twenty) (10, ten)");
map< int, string, greater<int> > copied_m(m); map<int, string, greater<> > copied_m(m);
CHECK_EQ(m, copied_m); // This must compile. CHECK_EQ(m, copied_m); // This must compile.
} }
#ifdef GLOG_STL_LOGGING_FOR_EXT_HASH
{
// Test a hashed simple associative container.
// Use a user defined hash function.
hash_set<int, user_hash> hs;
hs.insert(10);
hs.insert(20);
hs.insert(30);
ostringstream ss;
ss << hs;
EXPECT_EQ(ss.str().size(), 8);
EXPECT_TRUE(ss.str().find("10") != string::npos);
EXPECT_TRUE(ss.str().find("20") != string::npos);
EXPECT_TRUE(ss.str().find("30") != string::npos);
hash_set<int, user_hash> copied_hs(hs);
CHECK_EQ(hs, copied_hs); // This must compile.
}
#endif
} }
int main(int, char**) { int main(int, char**) {
@ -192,16 +112,3 @@ int main(int, char**) {
std::cout << "PASS\n"; std::cout << "PASS\n";
return 0; return 0;
} }
#else
#include <iostream>
int main(int, char**) {
std::cout << "We don't support stl_logging for this compiler.\n"
<< "(we need compiler support of 'using ::operator<<' "
<< "for this feature.)\n";
return 0;
}
#endif // HAVE_USING_OPERATOR

View File

@ -78,13 +78,13 @@ static int AssertFail() {
#define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail()) #define SAFE_ASSERT(expr) ((expr) ? 0 : AssertFail())
static SymbolizeCallback g_symbolize_callback = NULL; static SymbolizeCallback g_symbolize_callback = nullptr;
void InstallSymbolizeCallback(SymbolizeCallback callback) { void InstallSymbolizeCallback(SymbolizeCallback callback) {
g_symbolize_callback = callback; g_symbolize_callback = callback;
} }
static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback = static SymbolizeOpenObjectFileCallback g_symbolize_open_object_file_callback =
NULL; nullptr;
void InstallSymbolizeOpenObjectFileCallback( void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback) { SymbolizeOpenObjectFileCallback callback) {
g_symbolize_open_object_file_callback = callback; g_symbolize_open_object_file_callback = callback;
@ -118,21 +118,22 @@ _END_GOOGLE_NAMESPACE_
#else #else
#include <elf.h> #include <elf.h>
#endif #endif
#include <cerrno>
#include <climits>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <fcntl.h> #include <fcntl.h>
#include <stdint.h> #include <glog/raw_logging.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <unistd.h> #include <unistd.h>
#include "symbolize.h" #include <cerrno>
#include <climits>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include "config.h" #include "config.h"
#include <glog/raw_logging.h> #include "symbolize.h"
// Re-runs fn until it doesn't cause EINTR. // Re-runs fn until it doesn't cause EINTR.
#define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR) #define NO_INTR(fn) do {} while ((fn) < 0 && errno == EINTR)
@ -278,7 +279,7 @@ static ATTRIBUTE_NOINLINE bool
FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size, FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
uint64_t symbol_offset, const ElfW(Shdr) *strtab, uint64_t symbol_offset, const ElfW(Shdr) *strtab,
const ElfW(Shdr) *symtab) { const ElfW(Shdr) *symtab) {
if (symtab == NULL) { if (symtab == nullptr) {
return false; return false;
} }
const size_t num_symbols = symtab->sh_size / symtab->sh_entsize; const size_t num_symbols = symtab->sh_size / symtab->sh_entsize;
@ -312,7 +313,7 @@ FindSymbol(uint64_t pc, const int fd, char *out, size_t out_size,
start_address <= pc && pc < end_address) { start_address <= pc && pc < end_address) {
ssize_t len1 = ReadFromOffset(fd, out, out_size, ssize_t len1 = ReadFromOffset(fd, out, out_size,
strtab->sh_offset + symbol.st_name); strtab->sh_offset + symbol.st_name);
if (len1 <= 0 || memchr(out, '\0', out_size) == NULL) { if (len1 <= 0 || memchr(out, '\0', out_size) == nullptr) {
memset(out, 0, out_size); memset(out, 0, out_size);
return false; return false;
} }
@ -382,8 +383,8 @@ struct FileDescriptor {
int get() { return fd_; } int get() { return fd_; }
private: private:
FileDescriptor(const FileDescriptor &); FileDescriptor(const FileDescriptor &) = delete;
void operator=(const FileDescriptor&); void operator=(const FileDescriptor &) = delete;
}; };
// Helper class for reading lines from file. // Helper class for reading lines from file.
@ -420,7 +421,7 @@ class LineReader {
bol_ = eol_ + 1; // Advance to the next line in the buffer. bol_ = eol_ + 1; // Advance to the next line in the buffer.
SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_". SAFE_ASSERT(bol_ <= eod_); // "bol_" can point to "eod_".
if (!HasCompleteLine()) { if (!HasCompleteLine()) {
const size_t incomplete_line_length = static_cast<size_t>(eod_ - bol_); const auto incomplete_line_length = static_cast<size_t>(eod_ - bol_);
// Move the trailing incomplete line to the beginning. // Move the trailing incomplete line to the beginning.
memmove(buf_, bol_, incomplete_line_length); memmove(buf_, bol_, incomplete_line_length);
// Read text from file and append it. // Read text from file and append it.
@ -437,7 +438,7 @@ class LineReader {
} }
} }
eol_ = FindLineFeed(); eol_ = FindLineFeed();
if (eol_ == NULL) { // '\n' not found. Malformed line. if (eol_ == nullptr) { // '\n' not found. Malformed line.
return false; return false;
} }
*eol_ = '\0'; // Replace '\n' with '\0'. *eol_ = '\0'; // Replace '\n' with '\0'.
@ -458,8 +459,8 @@ class LineReader {
} }
private: private:
LineReader(const LineReader &); LineReader(const LineReader &) = delete;
void operator=(const LineReader&); void operator=(const LineReader &) = delete;
char *FindLineFeed() { char *FindLineFeed() {
return reinterpret_cast<char *>(memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_))); return reinterpret_cast<char *>(memchr(bol_, '\n', static_cast<size_t>(eod_ - bol_)));
@ -470,7 +471,7 @@ class LineReader {
} }
bool HasCompleteLine() { bool HasCompleteLine() {
return !BufferIsEmpty() && FindLineFeed() != NULL; return !BufferIsEmpty() && FindLineFeed() != nullptr;
} }
const int fd_; const int fd_;
@ -667,20 +668,20 @@ OpenObjectFileContainingPcAndGetStartAddress(uint64_t pc,
// POSIX doesn't define any async-signal safe function for converting // POSIX doesn't define any async-signal safe function for converting
// an integer to ASCII. We'll have to define our own version. // an integer to ASCII. We'll have to define our own version.
// itoa_r() converts an (unsigned) integer to ASCII. It returns "buf", if the // itoa_r() converts an (unsigned) integer to ASCII. It returns "buf", if the
// conversion was successful or NULL otherwise. It never writes more than "sz" // conversion was successful or nullptr otherwise. It never writes more than
// bytes. Output will be truncated as needed, and a NUL character is always // "sz" bytes. Output will be truncated as needed, and a NUL character is always
// appended. // appended.
// NOTE: code from sandbox/linux/seccomp-bpf/demo.cc. // NOTE: code from sandbox/linux/seccomp-bpf/demo.cc.
static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t padding) { static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t padding) {
// Make sure we can write at least one NUL byte. // Make sure we can write at least one NUL byte.
size_t n = 1; size_t n = 1;
if (n > sz) { if (n > sz) {
return NULL; return nullptr;
} }
if (base < 2 || base > 16) { if (base < 2 || base > 16) {
buf[0] = '\000'; buf[0] = '\000';
return NULL; return nullptr;
} }
char *start = buf; char *start = buf;
@ -692,7 +693,7 @@ static char *itoa_r(uintptr_t i, char *buf, size_t sz, unsigned base, size_t pad
// Make sure there is still enough space left in our output buffer. // Make sure there is still enough space left in our output buffer.
if (++n > sz) { if (++n > sz) {
buf[0] = '\000'; buf[0] = '\000';
return NULL; return nullptr;
} }
// Output the next digit. // Output the next digit.
@ -750,7 +751,7 @@ static void SafeAppendHexNumber(uint64_t value, char* dest, size_t dest_size) {
// get inlined. // get inlined.
static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out, static ATTRIBUTE_NOINLINE bool SymbolizeAndDemangle(void *pc, char *out,
size_t out_size) { size_t out_size) {
uint64_t pc0 = reinterpret_cast<uintptr_t>(pc); auto pc0 = reinterpret_cast<uintptr_t>(pc);
uint64_t start_address = 0; uint64_t start_address = 0;
uint64_t base_address = 0; uint64_t base_address = 0;
int object_fd = -1; int object_fd = -1;
@ -874,7 +875,7 @@ class SymInitializer {
public: public:
HANDLE process; HANDLE process;
bool ready; bool ready;
SymInitializer() : process(NULL), ready(false) { SymInitializer() : process(nullptr), ready(false) {
// Initialize the symbol handler. // Initialize the symbol handler.
// https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx // https://msdn.microsoft.com/en-us/library/windows/desktop/ms680344(v=vs.85).aspx
process = GetCurrentProcess(); process = GetCurrentProcess();
@ -882,7 +883,7 @@ public:
// We do not request undecorated symbols with SYMOPT_UNDNAME // We do not request undecorated symbols with SYMOPT_UNDNAME
// because the mangling library calls UnDecorateSymbolName. // because the mangling library calls UnDecorateSymbolName.
SymSetOptions(SYMOPT_DEFERRED_LOADS); SymSetOptions(SYMOPT_DEFERRED_LOADS);
if (SymInitialize(process, NULL, true)) { if (SymInitialize(process, nullptr, true)) {
ready = true; ready = true;
} }
} }

View File

@ -116,11 +116,7 @@ _START_GOOGLE_NAMESPACE_
// counter "pc". The callback function should write output to "out" // counter "pc". The callback function should write output to "out"
// and return the size of the output written. On error, the callback // and return the size of the output written. On error, the callback
// function should return -1. // function should return -1.
typedef int (*SymbolizeCallback)(int fd, using SymbolizeCallback = int (*)(int, void *, char *, size_t, uint64_t);
void* pc,
char* out,
size_t out_size,
uint64_t relocation);
GLOG_EXPORT GLOG_EXPORT
void InstallSymbolizeCallback(SymbolizeCallback callback); void InstallSymbolizeCallback(SymbolizeCallback callback);
@ -134,11 +130,8 @@ void InstallSymbolizeCallback(SymbolizeCallback callback);
// file is opened successfully, returns the file descriptor. Otherwise, // file is opened successfully, returns the file descriptor. Otherwise,
// returns -1. |out_file_name_size| is the size of the file name buffer // returns -1. |out_file_name_size| is the size of the file name buffer
// (including the null-terminator). // (including the null-terminator).
typedef int (*SymbolizeOpenObjectFileCallback)(uint64_t pc, using SymbolizeOpenObjectFileCallback = int (*)(uint64_t, uint64_t &,
uint64_t& start_address, uint64_t &, char *, size_t);
uint64_t& base_address,
char* out_file_name,
size_t out_file_name_size);
void InstallSymbolizeOpenObjectFileCallback( void InstallSymbolizeOpenObjectFileCallback(
SymbolizeOpenObjectFileCallback callback); SymbolizeOpenObjectFileCallback callback);

View File

@ -68,7 +68,7 @@ static const char *TrySymbolize(void *pc) {
if (Symbolize(pc, symbol, sizeof(symbol))) { if (Symbolize(pc, symbol, sizeof(symbol))) {
return symbol; return symbol;
} else { } else {
return NULL; return nullptr;
} }
} }
#endif #endif
@ -123,12 +123,12 @@ TEST(Symbolize, Symbolize) {
TrySymbolize(reinterpret_cast<void *>(&static_func)); TrySymbolize(reinterpret_cast<void *>(&static_func));
#if !defined(_MSC_VER) || !defined(NDEBUG) #if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(NULL != static_func_symbol); CHECK(nullptr != static_func_symbol);
EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 || EXPECT_TRUE(strcmp("static_func", static_func_symbol) == 0 ||
strcmp("static_func()", static_func_symbol) == 0); strcmp("static_func()", static_func_symbol) == 0);
#endif #endif
EXPECT_TRUE(NULL == TrySymbolize(NULL)); EXPECT_TRUE(nullptr == TrySymbolize(nullptr));
} }
struct Foo { struct Foo {
@ -181,7 +181,7 @@ static void SymbolizeSignalHandler(int /*signo*/) {
sizeof(g_symbolize_buffer))) { sizeof(g_symbolize_buffer))) {
g_symbolize_result = g_symbolize_buffer; g_symbolize_result = g_symbolize_buffer;
} else { } else {
g_symbolize_result = NULL; g_symbolize_result = nullptr;
} }
} }
@ -278,9 +278,9 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed; LOG(INFO) << "Stack consumption of Symbolize: " << *stack_consumed;
// Now restore the old alt-signal-stack and signal handlers. // Now restore the old alt-signal-stack and signal handlers.
CHECK_ERR(sigaltstack(&old_sigstk, NULL)); CHECK_ERR(sigaltstack(&old_sigstk, nullptr));
CHECK_ERR(sigaction(SIGUSR1, &old_sa1, NULL)); CHECK_ERR(sigaction(SIGUSR1, &old_sa1, nullptr));
CHECK_ERR(sigaction(SIGUSR2, &old_sa2, NULL)); CHECK_ERR(sigaction(SIGUSR2, &old_sa2, nullptr));
return g_symbolize_result; return g_symbolize_result;
} }
@ -307,7 +307,7 @@ TEST(Symbolize, SymbolizeStackConsumption) {
// mangled or an unmangled name here. // mangled or an unmangled name here.
symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&static_func), symbol = SymbolizeStackConsumption(reinterpret_cast<void *>(&static_func),
&stack_consumed); &stack_consumed);
CHECK(NULL != symbol); CHECK(nullptr != symbol);
EXPECT_TRUE(strcmp("static_func", symbol) == 0 || EXPECT_TRUE(strcmp("static_func", symbol) == 0 ||
strcmp("static_func()", symbol) == 0); strcmp("static_func()", symbol) == 0);
EXPECT_GT(stack_consumed, 0); EXPECT_GT(stack_consumed, 0);
@ -334,7 +334,7 @@ TEST(Symbolize, SymbolizeWithDemanglingStackConsumption) {
// x86 specific tests. Uses some inline assembler. // x86 specific tests. Uses some inline assembler.
extern "C" { extern "C" {
inline void* always_inline inline_func() { inline void* always_inline inline_func() {
void *pc = NULL; void *pc = nullptr;
#ifdef TEST_X86_32_AND_64 #ifdef TEST_X86_32_AND_64
__asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
#endif #endif
@ -343,7 +343,7 @@ inline void* always_inline inline_func() {
void* ATTRIBUTE_NOINLINE non_inline_func(); void* ATTRIBUTE_NOINLINE non_inline_func();
void* ATTRIBUTE_NOINLINE non_inline_func() { void* ATTRIBUTE_NOINLINE non_inline_func() {
void *pc = NULL; void *pc = nullptr;
#ifdef TEST_X86_32_AND_64 #ifdef TEST_X86_32_AND_64
__asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc)); __asm__ __volatile__("call 1f; 1: pop %0" : "=r"(pc));
#endif #endif
@ -356,7 +356,7 @@ static void ATTRIBUTE_NOINLINE TestWithPCInsideNonInlineFunction() {
const char *symbol = TrySymbolize(pc); const char *symbol = TrySymbolize(pc);
#if !defined(_MSC_VER) || !defined(NDEBUG) #if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != NULL); CHECK(symbol != nullptr);
CHECK_STREQ(symbol, "non_inline_func"); CHECK_STREQ(symbol, "non_inline_func");
#endif #endif
cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl; cout << "Test case TestWithPCInsideNonInlineFunction passed." << endl;
@ -369,7 +369,7 @@ static void ATTRIBUTE_NOINLINE TestWithPCInsideInlineFunction() {
const char *symbol = TrySymbolize(pc); const char *symbol = TrySymbolize(pc);
#if !defined(_MSC_VER) || !defined(NDEBUG) #if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != NULL); CHECK(symbol != nullptr);
CHECK_STREQ(symbol, __FUNCTION__); CHECK_STREQ(symbol, __FUNCTION__);
#endif #endif
cout << "Test case TestWithPCInsideInlineFunction passed." << endl; cout << "Test case TestWithPCInsideInlineFunction passed." << endl;
@ -384,7 +384,7 @@ static void ATTRIBUTE_NOINLINE TestWithReturnAddress() {
const char *symbol = TrySymbolize(return_address); const char *symbol = TrySymbolize(return_address);
#if !defined(_MSC_VER) || !defined(NDEBUG) #if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != NULL); CHECK(symbol != nullptr);
CHECK_STREQ(symbol, "main"); CHECK_STREQ(symbol, "main");
#endif #endif
cout << "Test case TestWithReturnAddress passed." << endl; cout << "Test case TestWithReturnAddress passed." << endl;
@ -428,7 +428,7 @@ __declspec(noinline) void TestWithReturnAddress() {
; ;
const char *symbol = TrySymbolize(return_address); const char *symbol = TrySymbolize(return_address);
#if !defined(_MSC_VER) || !defined(NDEBUG) #if !defined(_MSC_VER) || !defined(NDEBUG)
CHECK(symbol != NULL); CHECK(symbol != nullptr);
CHECK_STREQ(symbol, "main"); CHECK_STREQ(symbol, "main");
#endif #endif
cout << "Test case TestWithReturnAddress passed." << endl; cout << "Test case TestWithReturnAddress passed." << endl;
@ -444,7 +444,7 @@ int main(int argc, char **argv) {
# if defined(__ELF__) # if defined(__ELF__)
// We don't want to get affected by the callback interface, that may be // We don't want to get affected by the callback interface, that may be
// used to install some callback function at InitGoogle() time. // used to install some callback function at InitGoogle() time.
InstallSymbolizeCallback(NULL); InstallSymbolizeCallback(nullptr);
TestWithPCInsideInlineFunction(); TestWithPCInsideInlineFunction();
TestWithPCInsideNonInlineFunction(); TestWithPCInsideNonInlineFunction();

View File

@ -64,10 +64,10 @@ using std::string;
_START_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_
static const char* g_program_invocation_short_name = NULL; static const char* g_program_invocation_short_name = nullptr;
bool IsGoogleLoggingInitialized() { bool IsGoogleLoggingInitialized() {
return g_program_invocation_short_name != NULL; return g_program_invocation_short_name != nullptr;
} }
_END_GOOGLE_NAMESPACE_ _END_GOOGLE_NAMESPACE_
@ -84,7 +84,7 @@ GLOG_DEFINE_bool(symbolize_stacktrace, true,
_START_GOOGLE_NAMESPACE_ _START_GOOGLE_NAMESPACE_
typedef void DebugWriter(const char*, void*); using DebugWriter = void(const char*, void*);
// The %p field width for printf() functions is two characters per byte. // The %p field width for printf() functions is two characters per byte.
// For some environments, add two extra bytes for the leading "0x". // For some environments, add two extra bytes for the leading "0x".
@ -152,13 +152,12 @@ static void DumpStackTrace(int skip_count, DebugWriter *writerfn, void *arg) {
} }
} }
#if defined(__GNUC__) #ifdef __GNUC__
__attribute__((noreturn)) __attribute__((noreturn))
#elif defined(_MSC_VER)
__declspec(noreturn)
#endif #endif
static void DumpStackTraceAndExit() { static void
DumpStackTrace(1, DebugWriteToStderr, NULL); DumpStackTraceAndExit() {
DumpStackTrace(1, DebugWriteToStderr, nullptr);
// TODO(hamaji): Use signal instead of sigaction? // TODO(hamaji): Use signal instead of sigaction?
if (IsFailureSignalHandlerInstalled()) { if (IsFailureSignalHandlerInstalled()) {
@ -169,7 +168,7 @@ static void DumpStackTraceAndExit() {
memset(&sig_action, 0, sizeof(sig_action)); memset(&sig_action, 0, sizeof(sig_action));
sigemptyset(&sig_action.sa_mask); sigemptyset(&sig_action.sa_mask);
sig_action.sa_handler = SIG_DFL; sig_action.sa_handler = SIG_DFL;
sigaction(SIGABRT, &sig_action, NULL); sigaction(SIGABRT, &sig_action, nullptr);
#elif defined(GLOG_OS_WINDOWS) #elif defined(GLOG_OS_WINDOWS)
signal(SIGABRT, SIG_DFL); signal(SIGABRT, SIG_DFL);
#endif // HAVE_SIGACTION #endif // HAVE_SIGACTION
@ -187,7 +186,7 @@ _START_GOOGLE_NAMESPACE_
namespace glog_internal_namespace_ { namespace glog_internal_namespace_ {
const char* ProgramInvocationShortName() { const char* ProgramInvocationShortName() {
if (g_program_invocation_short_name != NULL) { if (g_program_invocation_short_name != nullptr) {
return g_program_invocation_short_name; return g_program_invocation_short_name;
} else { } else {
// TODO(hamaji): Use /proc/self/cmdline and so? // TODO(hamaji): Use /proc/self/cmdline and so?
@ -229,7 +228,7 @@ static int gettimeofday(struct timeval *tv, void* /*tz*/) {
int64 CycleClock_Now() { int64 CycleClock_Now() {
// TODO(hamaji): temporary impementation - it might be too slow. // TODO(hamaji): temporary impementation - it might be too slow.
struct timeval tv; struct timeval tv;
gettimeofday(&tv, NULL); gettimeofday(&tv, nullptr);
return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec; return static_cast<int64>(tv.tv_sec) * 1000000 + tv.tv_usec;
} }
@ -272,10 +271,10 @@ pid_t GetTID() {
if (!lacks_gettid) { if (!lacks_gettid) {
#if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP)) #if (defined(GLOG_OS_MACOSX) && defined(HAVE_PTHREAD_THREADID_NP))
uint64_t tid64; uint64_t tid64;
const int error = pthread_threadid_np(NULL, &tid64); const int error = pthread_threadid_np(nullptr, &tid64);
pid_t tid = error ? -1 : static_cast<pid_t>(tid64); pid_t tid = error ? -1 : static_cast<pid_t>(tid64);
#else #else
pid_t tid = static_cast<pid_t>(syscall(__NR_gettid)); auto tid = static_cast<pid_t>(syscall(__NR_gettid));
#endif #endif
if (tid != -1) { if (tid != -1) {
return tid; return tid;
@ -321,12 +320,12 @@ static void MyUserNameInitializer() {
#else #else
const char* user = getenv("USER"); const char* user = getenv("USER");
#endif #endif
if (user != NULL) { if (user != nullptr) {
g_my_user_name = user; g_my_user_name = user;
} else { } else {
#if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H) #if defined(HAVE_PWD_H) && defined(HAVE_UNISTD_H)
struct passwd pwd; struct passwd pwd;
struct passwd* result = NULL; struct passwd* result = nullptr;
char buffer[1024] = {'\0'}; char buffer[1024] = {'\0'};
uid_t uid = geteuid(); uid_t uid = geteuid();
int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result); int pwuid_res = getpwuid_r(uid, &pwd, buffer, sizeof(buffer), &result);
@ -341,7 +340,6 @@ static void MyUserNameInitializer() {
g_my_user_name = "invalid-user"; g_my_user_name = "invalid-user";
} }
} }
} }
REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer()) REGISTER_MODULE_INITIALIZER(utilities, MyUserNameInitializer())
@ -353,7 +351,7 @@ void DumpStackTraceToString(string* stacktrace) {
// We use an atomic operation to prevent problems with calling CrashReason // We use an atomic operation to prevent problems with calling CrashReason
// from inside the Mutex implementation (potentially through RAW_CHECK). // from inside the Mutex implementation (potentially through RAW_CHECK).
static const CrashReason* g_reason = 0; static const CrashReason* g_reason = nullptr;
void SetCrashReason(const CrashReason* r) { void SetCrashReason(const CrashReason* r) {
sync_val_compare_and_swap(&g_reason, sync_val_compare_and_swap(&g_reason,
@ -378,7 +376,7 @@ void InitGoogleLoggingUtilities(const char* argv0) {
void ShutdownGoogleLoggingUtilities() { void ShutdownGoogleLoggingUtilities() {
CHECK(IsGoogleLoggingInitialized()) CHECK(IsGoogleLoggingInitialized())
<< "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!"; << "You called ShutdownGoogleLogging() without calling InitGoogleLogging() first!";
g_program_invocation_short_name = NULL; g_program_invocation_short_name = nullptr;
#ifdef HAVE_SYSLOG_H #ifdef HAVE_SYSLOG_H
closelog(); closelog();
#endif #endif

View File

@ -191,16 +191,16 @@ inline T sync_val_compare_and_swap(T* ptr, T oldval, T newval) {
void DumpStackTraceToString(std::string* stacktrace); void DumpStackTraceToString(std::string* stacktrace);
struct CrashReason { struct CrashReason {
CrashReason() : filename(0), line_number(0), message(0), depth(0) {} CrashReason() = default;
const char* filename; const char* filename{nullptr};
int line_number; int line_number{0};
const char* message; const char* message{nullptr};
// We'll also store a bit of stack trace context at the time of crash as // We'll also store a bit of stack trace context at the time of crash as
// it may not be available later on. // it may not be available later on.
void* stack[32]; void* stack[32];
int depth; int depth{0};
}; };
void SetCrashReason(const CrashReason* r); void SetCrashReason(const CrashReason* r);

View File

@ -74,7 +74,7 @@ GLOG_EXPORT bool SafeFNMatch_(const char* pattern, size_t patt_len,
const char* str, size_t str_len) { const char* str, size_t str_len) {
size_t p = 0; size_t p = 0;
size_t s = 0; size_t s = 0;
while (1) { while (true) {
if (p == patt_len && s == str_len) return true; if (p == patt_len && s == str_len) return true;
if (p == patt_len) return false; if (p == patt_len) return false;
if (s == str_len) return p+1 == patt_len && pattern[p] == '*'; if (s == str_len) return p+1 == patt_len && pattern[p] == '*';
@ -120,8 +120,8 @@ struct VModuleInfo {
static Mutex vmodule_lock; static Mutex vmodule_lock;
// Pointer to head of the VModuleInfo list. // Pointer to head of the VModuleInfo list.
// It's a map from module pattern to logging level for those module(s). // It's a map from module pattern to logging level for those module(s).
static VModuleInfo* vmodule_list = 0; static VModuleInfo* vmodule_list = nullptr;
static SiteFlag* cached_site_list = 0; static SiteFlag* cached_site_list = nullptr;
// Boolean initialization flag. // Boolean initialization flag.
static bool inited_vmodule = false; static bool inited_vmodule = false;
@ -134,13 +134,13 @@ static void VLOG2Initializer() {
inited_vmodule = false; inited_vmodule = false;
const char* vmodule = FLAGS_vmodule.c_str(); const char* vmodule = FLAGS_vmodule.c_str();
const char* sep; const char* sep;
VModuleInfo* head = NULL; VModuleInfo* head = nullptr;
VModuleInfo* tail = NULL; VModuleInfo* tail = nullptr;
while ((sep = strchr(vmodule, '=')) != NULL) { while ((sep = strchr(vmodule, '=')) != nullptr) {
string pattern(vmodule, static_cast<size_t>(sep - vmodule)); string pattern(vmodule, static_cast<size_t>(sep - vmodule));
int module_level; int module_level;
if (sscanf(sep, "=%d", &module_level) == 1) { if (sscanf(sep, "=%d", &module_level) == 1) {
VModuleInfo* info = new VModuleInfo; auto* info = new VModuleInfo;
info->module_pattern = pattern; info->module_pattern = pattern;
info->vlog_level = module_level; info->vlog_level = module_level;
if (head) { if (head) {
@ -152,7 +152,7 @@ static void VLOG2Initializer() {
} }
// Skip past this entry // Skip past this entry
vmodule = strchr(sep, ','); vmodule = strchr(sep, ',');
if (vmodule == NULL) break; if (vmodule == nullptr) break;
vmodule++; // Skip past "," vmodule++; // Skip past ","
} }
if (head) { // Put them into the list at the head: if (head) { // Put them into the list at the head:
@ -169,8 +169,8 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
bool found = false; bool found = false;
{ {
MutexLock l(&vmodule_lock); // protect whole read-modify-write MutexLock l(&vmodule_lock); // protect whole read-modify-write
for (const VModuleInfo* info = vmodule_list; for (const VModuleInfo* info = vmodule_list; info != nullptr;
info != NULL; info = info->next) { info = info->next) {
if (info->module_pattern == module_pattern) { if (info->module_pattern == module_pattern) {
if (!found) { if (!found) {
result = info->vlog_level; result = info->vlog_level;
@ -186,7 +186,7 @@ int SetVLOGLevel(const char* module_pattern, int log_level) {
} }
} }
if (!found) { if (!found) {
VModuleInfo* info = new VModuleInfo; auto* info = new VModuleInfo;
info->module_pattern = module_pattern; info->module_pattern = module_pattern;
info->vlog_level = log_level; info->vlog_level = log_level;
info->next = vmodule_list; info->next = vmodule_list;
@ -242,7 +242,8 @@ bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
base = base ? (base+1) : fname; base = base ? (base+1) : fname;
const char* base_end = strchr(base, '.'); const char* base_end = strchr(base, '.');
size_t base_length = base_end ? size_t(base_end - base) : strlen(base); size_t base_length =
base_end ? static_cast<size_t>(base_end - base) : strlen(base);
// Trim out trailing "-inl" if any // Trim out trailing "-inl" if any
if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) { if (base_length >= 4 && (memcmp(base+base_length-4, "-inl", 4) == 0)) {
@ -254,8 +255,8 @@ bool InitVLOG3__(SiteFlag* site_flag, int32* level_default,
// find target in vector of modules, replace site_flag_value with // find target in vector of modules, replace site_flag_value with
// a module-specific verbose level, if any. // a module-specific verbose level, if any.
for (const VModuleInfo* info = vmodule_list; for (const VModuleInfo* info = vmodule_list; info != nullptr;
info != NULL; info = info->next) { info = info->next) {
if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(), if (SafeFNMatch_(info->module_pattern.c_str(), info->module_pattern.size(),
base, base_length)) { base, base_length)) {
site_flag_value = &info->vlog_level; site_flag_value = &info->vlog_level;

View File

@ -352,20 +352,20 @@ _wopendir(
wchar_t *p; wchar_t *p;
/* Must have directory name */ /* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') { if (dirname == nullptr || dirname[0] == '\0') {
dirent_set_errno (ENOENT); dirent_set_errno(ENOENT);
return NULL; return nullptr;
} }
/* Allocate new _WDIR structure */ /* Allocate new _WDIR structure */
dirp = (_WDIR*) malloc (sizeof (struct _WDIR)); dirp = (_WDIR*) malloc (sizeof (struct _WDIR));
if (!dirp) { if (!dirp) {
return NULL; return nullptr;
} }
/* Reset _WDIR structure */ /* Reset _WDIR structure */
dirp->handle = INVALID_HANDLE_VALUE; dirp->handle = INVALID_HANDLE_VALUE;
dirp->patt = NULL; dirp->patt = nullptr;
dirp->cached = 0; dirp->cached = 0;
/* /*
@ -376,7 +376,7 @@ _wopendir(
*/ */
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/* Desktop */ /* Desktop */
n = GetFullPathNameW (dirname, 0, NULL, NULL); n = GetFullPathNameW(dirname, 0, nullptr, nullptr);
#else #else
/* WinRT */ /* WinRT */
n = wcslen (dirname); n = wcslen (dirname);
@ -384,8 +384,8 @@ _wopendir(
/* Allocate room for absolute directory name and search pattern */ /* Allocate room for absolute directory name and search pattern */
dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16); dirp->patt = (wchar_t*) malloc (sizeof (wchar_t) * n + 16);
if (dirp->patt == NULL) { if (dirp->patt == nullptr) {
goto exit_closedir; goto exit_closedir;
} }
/* /*
@ -398,7 +398,7 @@ _wopendir(
*/ */
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) #if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
/* Desktop */ /* Desktop */
n = GetFullPathNameW (dirname, n, dirp->patt, NULL); n = GetFullPathNameW(dirname, n, dirp->patt, nullptr);
if (n <= 0) { if (n <= 0) {
goto exit_closedir; goto exit_closedir;
} }
@ -435,7 +435,7 @@ _wopendir(
/* Failure */ /* Failure */
exit_closedir: exit_closedir:
_wclosedir (dirp); _wclosedir (dirp);
return NULL; return nullptr;
} }
/* /*
@ -452,7 +452,7 @@ _wreaddir(
/* /*
* Read directory entry to buffer. We can safely ignore the return value * Read directory entry to buffer. We can safely ignore the return value
* as entry will be set to NULL in case of error. * as entry will be set to nullptr in case of error.
*/ */
(void) _wreaddir_r (dirp, &dirp->ent, &entry); (void) _wreaddir_r (dirp, &dirp->ent, &entry);
@ -464,7 +464,7 @@ _wreaddir(
* Read next directory entry. * Read next directory entry.
* *
* Returns zero on success. If end of directory stream is reached, then sets * Returns zero on success. If end of directory stream is reached, then sets
* result to NULL and returns zero. * result to nullptr and returns zero.
*/ */
static int static int
_wreaddir_r( _wreaddir_r(
@ -514,10 +514,8 @@ _wreaddir_r(
*result = entry; *result = entry;
} else { } else {
/* Return nullptr to indicate end of directory */
/* Return NULL to indicate end of directory */ *result = nullptr;
*result = NULL;
} }
return /*OK*/0; return /*OK*/0;
@ -585,9 +583,8 @@ dirent_first(
DWORD error; DWORD error;
/* Open directory and retrieve the first entry */ /* Open directory and retrieve the first entry */
dirp->handle = FindFirstFileExW( dirp->handle = FindFirstFileExW(dirp->patt, FindExInfoStandard, &dirp->data,
dirp->patt, FindExInfoStandard, &dirp->data, FindExSearchNameMatch, nullptr, 0);
FindExSearchNameMatch, NULL, 0);
if (dirp->handle != INVALID_HANDLE_VALUE) { if (dirp->handle != INVALID_HANDLE_VALUE) {
/* a directory entry is now waiting in memory */ /* a directory entry is now waiting in memory */
@ -598,7 +595,7 @@ dirent_first(
/* Failed to open directory: no directory entry in memory */ /* Failed to open directory: no directory entry in memory */
dirp->cached = 0; dirp->cached = 0;
datap = NULL; datap = nullptr;
/* Set error code */ /* Set error code */
error = GetLastError (); error = GetLastError ();
@ -651,14 +648,13 @@ dirent_next(
/* The very last entry has been processed or an error occurred */ /* The very last entry has been processed or an error occurred */
FindClose (dirp->handle); FindClose (dirp->handle);
dirp->handle = INVALID_HANDLE_VALUE; dirp->handle = INVALID_HANDLE_VALUE;
p = NULL; p = nullptr;
} }
} else { } else {
/* End of directory stream reached */ /* End of directory stream reached */
p = NULL; p = nullptr;
} }
return p; return p;
@ -674,15 +670,15 @@ opendir(
struct DIR *dirp; struct DIR *dirp;
/* Must have directory name */ /* Must have directory name */
if (dirname == NULL || dirname[0] == '\0') { if (dirname == nullptr || dirname[0] == '\0') {
dirent_set_errno (ENOENT); dirent_set_errno (ENOENT);
return NULL; return nullptr;
} }
/* Allocate memory for DIR structure */ /* Allocate memory for DIR structure */
dirp = (DIR*) malloc (sizeof (struct DIR)); dirp = (DIR*) malloc (sizeof (struct DIR));
if (!dirp) { if (!dirp) {
return NULL; return nullptr;
} }
{ {
int error; int error;
@ -717,7 +713,7 @@ opendir(
/* Failure */ /* Failure */
exit_free: exit_free:
free (dirp); free (dirp);
return NULL; return nullptr;
} }
/* /*
@ -731,7 +727,7 @@ readdir(
/* /*
* Read directory entry to buffer. We can safely ignore the return value * Read directory entry to buffer. We can safely ignore the return value
* as entry will be set to NULL in case of error. * as entry will be set to nullptr in case of error.
*/ */
(void) readdir_r (dirp, &dirp->ent, &entry); (void) readdir_r (dirp, &dirp->ent, &entry);
@ -743,7 +739,7 @@ readdir(
* Read next directory entry into called-allocated buffer. * Read next directory entry into called-allocated buffer.
* *
* Returns zero on success. If the end of directory stream is reached, then * Returns zero on success. If the end of directory stream is reached, then
* sets result to NULL and returns zero. * sets result to nullptr and returns zero.
*/ */
static int static int
readdir_r( readdir_r(
@ -801,11 +797,10 @@ readdir_r(
entry->d_reclen = sizeof (struct dirent); entry->d_reclen = sizeof (struct dirent);
} else { } else {
/* /*
* Cannot convert file name to multi-byte string so construct * Cannot convert file name to multi-byte string so construct
* an erroneous directory entry and return that. Note that * an erroneous directory entry and return that. Note that
* we cannot return NULL as that would stop the processing * we cannot return nullptr as that would stop the processing
* of directory entries completely. * of directory entries completely.
*/ */
entry->d_name[0] = '?'; entry->d_name[0] = '?';
@ -824,8 +819,7 @@ readdir_r(
} else { } else {
/* No more directory entries */ /* No more directory entries */
*result = NULL; *result = nullptr;
} }
return /*OK*/0; return /*OK*/0;
@ -843,7 +837,7 @@ closedir(
/* Close wide-character directory stream */ /* Close wide-character directory stream */
ok = _wclosedir (dirp->wdirp); ok = _wclosedir (dirp->wdirp);
dirp->wdirp = NULL; dirp->wdirp = nullptr;
/* Release multi-byte character version */ /* Release multi-byte character version */
free (dirp); free (dirp);
@ -879,13 +873,13 @@ scandir(
int (*filter)(const struct dirent*), int (*filter)(const struct dirent*),
int (*compare)(const struct dirent**, const struct dirent**)) int (*compare)(const struct dirent**, const struct dirent**))
{ {
struct dirent **files = NULL; struct dirent **files = nullptr;
size_t size = 0; size_t size = 0;
size_t allocated = 0; size_t allocated = 0;
const size_t init_size = 1; const size_t init_size = 1;
DIR *dir = NULL; DIR *dir = nullptr;
struct dirent *entry; struct dirent *entry;
struct dirent *tmp = NULL; struct dirent *tmp = nullptr;
size_t i; size_t i;
int result = 0; int result = 0;
@ -912,7 +906,7 @@ scandir(
/* Allocate first pointer table or enlarge existing table */ /* Allocate first pointer table or enlarge existing table */
p = realloc (files, sizeof (void*) * num_entries); p = realloc (files, sizeof (void*) * num_entries);
if (p != NULL) { if (p != nullptr) {
/* Got the memory */ /* Got the memory */
files = (dirent**) p; files = (dirent**) p;
allocated = num_entries; allocated = num_entries;
@ -921,13 +915,12 @@ scandir(
result = -1; result = -1;
break; break;
} }
} }
/* Allocate room for temporary directory entry */ /* Allocate room for temporary directory entry */
if (tmp == NULL) { if (tmp == nullptr) {
tmp = (struct dirent*) malloc (sizeof (struct dirent)); tmp = (struct dirent*) malloc (sizeof (struct dirent));
if (tmp == NULL) { if (tmp == nullptr) {
/* Cannot allocate temporary directory entry */ /* Cannot allocate temporary directory entry */
result = -1; result = -1;
break; break;
@ -938,7 +931,7 @@ scandir(
if (readdir_r (dir, tmp, &entry) == /*OK*/0) { if (readdir_r (dir, tmp, &entry) == /*OK*/0) {
/* Did we get an entry? */ /* Did we get an entry? */
if (entry != NULL) { if (entry != nullptr) {
int pass; int pass;
/* Determine whether to include the entry in result */ /* Determine whether to include the entry in result */
@ -953,14 +946,13 @@ scandir(
if (pass) { if (pass) {
/* Store the temporary entry to pointer table */ /* Store the temporary entry to pointer table */
files[size++] = tmp; files[size++] = tmp;
tmp = NULL; tmp = nullptr;
/* Keep up with the number of files */ /* Keep up with the number of files */
result++; result++;
} }
} else { } else {
/* /*
* End of directory stream reached => sort entries and * End of directory stream reached => sort entries and
* exit. * exit.
@ -968,7 +960,6 @@ scandir(
qsort (files, size, sizeof (void*), qsort (files, size, sizeof (void*),
(int (*) (const void*, const void*)) compare); (int (*) (const void*, const void*)) compare);
break; break;
} }
} else { } else {
@ -993,7 +984,7 @@ scandir(
free (files[i]); free (files[i]);
} }
free (files); free (files);
files = NULL; files = nullptr;
} }
/* Close directory stream */ /* Close directory stream */

View File

@ -36,12 +36,16 @@
# error You should only be including windows/port.cc in a windows environment! # error You should only be including windows/port.cc in a windows environment!
#endif #endif
#include "config.h"
#include <cstdarg> // for va_list, va_start, va_end
#include "port.h" #include "port.h"
#include <cstdarg> // for va_list, va_start, va_end
#include <ctime>
#include "config.h"
// These call the windows _vsnprintf, but always NUL-terminate. // These call the windows _vsnprintf, but always NUL-terminate.
int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) { int safe_vsnprintf(char* str, std::size_t size, const char* format,
va_list ap) {
if (size == 0) // not even room for a \0? if (size == 0) // not even room for a \0?
return -1; // not what C99 says to do, but what windows does return -1; // not what C99 says to do, but what windows does
str[size-1] = '\0'; str[size-1] = '\0';
@ -49,15 +53,15 @@ int safe_vsnprintf(char *str, size_t size, const char *format, va_list ap) {
} }
#ifndef HAVE_LOCALTIME_R #ifndef HAVE_LOCALTIME_R
struct tm* localtime_r(const time_t* timep, struct tm* result) { struct tm* localtime_r(const std::time_t* timep, std::tm* result) {
localtime_s(result, timep); localtime_s(result, timep);
return result; return result;
} }
#endif // not HAVE_LOCALTIME_R #endif // not HAVE_LOCALTIME_R
#ifndef HAVE_GMTIME_R #ifndef HAVE_GMTIME_R
struct tm* gmtime_r(const time_t* timep, struct tm* result) { struct tm* gmtime_r(const std::time_t* timep, std::tm* result) {
gmtime_s(result, timep); gmtime_s(result, timep);
return result; return result;
} }
#endif // not HAVE_GMTIME_R #endif // not HAVE_GMTIME_R
#ifndef HAVE_SNPRINTF #ifndef HAVE_SNPRINTF

View File

@ -1,4 +1,4 @@
/* Copyright (c) 2008, Google Inc. /* Copyright (c) 2023, Google Inc.
* All rights reserved. * All rights reserved.
* *
* Redistribution and use in source and binary forms, with or without * Redistribution and use in source and binary forms, with or without
@ -158,15 +158,15 @@ enum { PTHREAD_ONCE_INIT = 0 }; // important that this be 0! for SpinLock
#endif // HAVE_PTHREAD #endif // HAVE_PTHREAD
#ifndef HAVE_LOCALTIME_R #ifndef HAVE_LOCALTIME_R
extern GLOG_EXPORT struct tm* localtime_r(const time_t* timep, extern GLOG_EXPORT std::tm* localtime_r(const std::time_t* timep,
struct tm* result); std::tm* result);
#endif // not HAVE_LOCALTIME_R #endif // not HAVE_LOCALTIME_R
#ifndef HAVE_GMTIME_R #ifndef HAVE_GMTIME_R
extern GLOG_EXPORT struct tm* gmtime_r(const time_t* timep, struct tm* result); extern GLOG_EXPORT std::tm* gmtime_r(const std::time_t* timep, std::tm* result);
#endif // not HAVE_GMTIME_R #endif // not HAVE_GMTIME_R
inline char* strerror_r(int errnum, char* buf, size_t buflen) { inline char* strerror_r(int errnum, char* buf, std::size_t buflen) {
strerror_s(buf, buflen, errnum); strerror_s(buf, buflen, errnum);
return buf; return buf;
} }