Repo created
This commit is contained in:
parent
81b91f4139
commit
f8c34fa5ee
22732 changed files with 4815320 additions and 2 deletions
117
TMessagesProj/jni/voip/webrtc/absl/log/absl_check.h
Normal file
117
TMessagesProj/jni/voip/webrtc/absl/log/absl_check.h
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/absl_check.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares a family of `ABSL_CHECK` macros as alternative spellings
|
||||
// for `CHECK` macros in `check.h`.
|
||||
//
|
||||
// Except for those whose names begin with `ABSL_DCHECK`, these macros are not
|
||||
// controlled by `NDEBUG` (cf. `assert`), so the check will be executed
|
||||
// regardless of compilation mode. `ABSL_CHECK` and friends are thus useful for
|
||||
// confirming invariants in situations where continuing to run would be worse
|
||||
// than terminating, e.g., due to risk of data corruption or security
|
||||
// compromise. It is also more robust and portable to deliberately terminate
|
||||
// at a particular place with a useful message and backtrace than to assume some
|
||||
// ultimately unspecified and unreliable crashing behavior (such as a
|
||||
// "segmentation fault").
|
||||
//
|
||||
// For full documentation of each macro, see comments in `check.h`, which has an
|
||||
// identical set of macros without the ABSL_* prefix.
|
||||
|
||||
#ifndef ABSL_LOG_ABSL_CHECK_H_
|
||||
#define ABSL_LOG_ABSL_CHECK_H_
|
||||
|
||||
#include "absl/log/internal/check_impl.h"
|
||||
|
||||
#define ABSL_CHECK(condition) \
|
||||
ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition)
|
||||
#define ABSL_QCHECK(condition) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition)
|
||||
#define ABSL_PCHECK(condition) \
|
||||
ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition)
|
||||
#define ABSL_DCHECK(condition) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition)
|
||||
|
||||
#define ABSL_CHECK_EQ(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_CHECK_NE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_CHECK_LE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_CHECK_LT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_CHECK_GE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_CHECK_GT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_QCHECK_EQ(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_QCHECK_NE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_QCHECK_LE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_QCHECK_LT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_QCHECK_GE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_QCHECK_GT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_DCHECK_EQ(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_DCHECK_NE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_DCHECK_LE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_DCHECK_LT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_DCHECK_GE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define ABSL_DCHECK_GT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)
|
||||
|
||||
#define ABSL_CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status)
|
||||
#define ABSL_QCHECK_OK(status) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status)
|
||||
#define ABSL_DCHECK_OK(status) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status)
|
||||
|
||||
#define ABSL_CHECK_STREQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_CHECK_STRNE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_CHECK_STRCASEEQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_CHECK_STRCASENE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_QCHECK_STREQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_QCHECK_STRNE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_QCHECK_STRCASEEQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_QCHECK_STRCASENE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_DCHECK_STREQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_DCHECK_STRNE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_DCHECK_STRCASEEQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define ABSL_DCHECK_STRCASENE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
|
||||
|
||||
#endif // ABSL_LOG_ABSL_CHECK_H_
|
||||
58
TMessagesProj/jni/voip/webrtc/absl/log/absl_check_test.cc
Normal file
58
TMessagesProj/jni/voip/webrtc/absl/log/absl_check_test.cc
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/absl_check.h"
|
||||
|
||||
#define ABSL_TEST_CHECK ABSL_CHECK
|
||||
#define ABSL_TEST_CHECK_OK ABSL_CHECK_OK
|
||||
#define ABSL_TEST_CHECK_EQ ABSL_CHECK_EQ
|
||||
#define ABSL_TEST_CHECK_NE ABSL_CHECK_NE
|
||||
#define ABSL_TEST_CHECK_GE ABSL_CHECK_GE
|
||||
#define ABSL_TEST_CHECK_LE ABSL_CHECK_LE
|
||||
#define ABSL_TEST_CHECK_GT ABSL_CHECK_GT
|
||||
#define ABSL_TEST_CHECK_LT ABSL_CHECK_LT
|
||||
#define ABSL_TEST_CHECK_STREQ ABSL_CHECK_STREQ
|
||||
#define ABSL_TEST_CHECK_STRNE ABSL_CHECK_STRNE
|
||||
#define ABSL_TEST_CHECK_STRCASEEQ ABSL_CHECK_STRCASEEQ
|
||||
#define ABSL_TEST_CHECK_STRCASENE ABSL_CHECK_STRCASENE
|
||||
|
||||
#define ABSL_TEST_DCHECK ABSL_DCHECK
|
||||
#define ABSL_TEST_DCHECK_OK ABSL_DCHECK_OK
|
||||
#define ABSL_TEST_DCHECK_EQ ABSL_DCHECK_EQ
|
||||
#define ABSL_TEST_DCHECK_NE ABSL_DCHECK_NE
|
||||
#define ABSL_TEST_DCHECK_GE ABSL_DCHECK_GE
|
||||
#define ABSL_TEST_DCHECK_LE ABSL_DCHECK_LE
|
||||
#define ABSL_TEST_DCHECK_GT ABSL_DCHECK_GT
|
||||
#define ABSL_TEST_DCHECK_LT ABSL_DCHECK_LT
|
||||
#define ABSL_TEST_DCHECK_STREQ ABSL_DCHECK_STREQ
|
||||
#define ABSL_TEST_DCHECK_STRNE ABSL_DCHECK_STRNE
|
||||
#define ABSL_TEST_DCHECK_STRCASEEQ ABSL_DCHECK_STRCASEEQ
|
||||
#define ABSL_TEST_DCHECK_STRCASENE ABSL_DCHECK_STRCASENE
|
||||
|
||||
#define ABSL_TEST_QCHECK ABSL_QCHECK
|
||||
#define ABSL_TEST_QCHECK_OK ABSL_QCHECK_OK
|
||||
#define ABSL_TEST_QCHECK_EQ ABSL_QCHECK_EQ
|
||||
#define ABSL_TEST_QCHECK_NE ABSL_QCHECK_NE
|
||||
#define ABSL_TEST_QCHECK_GE ABSL_QCHECK_GE
|
||||
#define ABSL_TEST_QCHECK_LE ABSL_QCHECK_LE
|
||||
#define ABSL_TEST_QCHECK_GT ABSL_QCHECK_GT
|
||||
#define ABSL_TEST_QCHECK_LT ABSL_QCHECK_LT
|
||||
#define ABSL_TEST_QCHECK_STREQ ABSL_QCHECK_STREQ
|
||||
#define ABSL_TEST_QCHECK_STRNE ABSL_QCHECK_STRNE
|
||||
#define ABSL_TEST_QCHECK_STRCASEEQ ABSL_QCHECK_STRCASEEQ
|
||||
#define ABSL_TEST_QCHECK_STRCASENE ABSL_QCHECK_STRCASENE
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/log/check_test_impl.inc"
|
||||
115
TMessagesProj/jni/voip/webrtc/absl/log/absl_log.h
Normal file
115
TMessagesProj/jni/voip/webrtc/absl/log/absl_log.h
Normal file
|
|
@ -0,0 +1,115 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/absl_log.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares a family of `ABSL_LOG` macros as alternative spellings
|
||||
// for macros in `log.h`.
|
||||
//
|
||||
// Basic invocation looks like this:
|
||||
//
|
||||
// ABSL_LOG(INFO) << "Found " << num_cookies << " cookies";
|
||||
//
|
||||
// Most `ABSL_LOG` macros take a severity level argument. The severity levels
|
||||
// are `INFO`, `WARNING`, `ERROR`, and `FATAL`.
|
||||
//
|
||||
// For full documentation, see comments in `log.h`, which includes full
|
||||
// reference documentation on use of the equivalent `LOG` macro and has an
|
||||
// identical set of macros without the ABSL_* prefix.
|
||||
|
||||
#ifndef ABSL_LOG_ABSL_LOG_H_
|
||||
#define ABSL_LOG_ABSL_LOG_H_
|
||||
|
||||
#include "absl/log/internal/log_impl.h"
|
||||
|
||||
#define ABSL_LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity)
|
||||
#define ABSL_PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity)
|
||||
#define ABSL_DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity)
|
||||
|
||||
#define ABSL_VLOG(verbose_level) ABSL_LOG_INTERNAL_VLOG_IMPL(verbose_level)
|
||||
#define ABSL_DVLOG(verbose_level) ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level)
|
||||
|
||||
#define ABSL_LOG_IF(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition)
|
||||
#define ABSL_PLOG_IF(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition)
|
||||
#define ABSL_DLOG_IF(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition)
|
||||
|
||||
#define ABSL_LOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n)
|
||||
#define ABSL_LOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n)
|
||||
#define ABSL_LOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity)
|
||||
#define ABSL_LOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
|
||||
|
||||
#define ABSL_PLOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n)
|
||||
#define ABSL_PLOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n)
|
||||
#define ABSL_PLOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity)
|
||||
#define ABSL_PLOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
|
||||
|
||||
#define ABSL_DLOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n)
|
||||
#define ABSL_DLOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n)
|
||||
#define ABSL_DLOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity)
|
||||
#define ABSL_DLOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
|
||||
|
||||
#define ABSL_VLOG_EVERY_N(verbose_level, n) \
|
||||
ABSL_LOG_INTERNAL_VLOG_EVERY_N_IMPL(verbose_level, n)
|
||||
#define ABSL_VLOG_FIRST_N(verbose_level, n) \
|
||||
ABSL_LOG_INTERNAL_VLOG_FIRST_N_IMPL(verbose_level, n)
|
||||
#define ABSL_VLOG_EVERY_POW_2(verbose_level, n) \
|
||||
ABSL_LOG_INTERNAL_VLOG_EVERY_POW_2_IMPL(verbose_level, n)
|
||||
#define ABSL_VLOG_EVERY_N_SEC(verbose_level, n) \
|
||||
ABSL_LOG_INTERNAL_VLOG_EVERY_N_SEC_IMPL(verbose_level, n)
|
||||
|
||||
#define ABSL_LOG_IF_EVERY_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
|
||||
#define ABSL_LOG_IF_FIRST_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
|
||||
#define ABSL_LOG_IF_EVERY_POW_2(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
|
||||
#define ABSL_LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
|
||||
|
||||
#define ABSL_PLOG_IF_EVERY_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
|
||||
#define ABSL_PLOG_IF_FIRST_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
|
||||
#define ABSL_PLOG_IF_EVERY_POW_2(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
|
||||
#define ABSL_PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
|
||||
|
||||
#define ABSL_DLOG_IF_EVERY_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
|
||||
#define ABSL_DLOG_IF_FIRST_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
|
||||
#define ABSL_DLOG_IF_EVERY_POW_2(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
|
||||
#define ABSL_DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
|
||||
|
||||
#endif // ABSL_LOG_ABSL_LOG_H_
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/absl_log.h"
|
||||
|
||||
#define ABSL_TEST_LOG ABSL_LOG
|
||||
#define ABSL_TEST_DLOG ABSL_DLOG
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/log/log_basic_test_impl.inc"
|
||||
95
TMessagesProj/jni/voip/webrtc/absl/log/absl_vlog_is_on.h
Normal file
95
TMessagesProj/jni/voip/webrtc/absl/log/absl_vlog_is_on.h
Normal file
|
|
@ -0,0 +1,95 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/absl_vlog_is_on.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header defines the `ABSL_VLOG_IS_ON()` macro that controls the
|
||||
// variable-verbosity conditional logging.
|
||||
//
|
||||
// It's used by `VLOG` in log.h, or it can also be used directly like this:
|
||||
//
|
||||
// if (ABSL_VLOG_IS_ON(2)) {
|
||||
// foo_server.RecomputeStatisticsExpensive();
|
||||
// LOG(INFO) << foo_server.LastStatisticsAsString();
|
||||
// }
|
||||
//
|
||||
// Each source file has an effective verbosity level that's a non-negative
|
||||
// integer computed from the `--vmodule` and `--v` flags.
|
||||
// `ABSL_VLOG_IS_ON(n)` is true, and `VLOG(n)` logs, if that effective verbosity
|
||||
// level is greater than or equal to `n`.
|
||||
//
|
||||
// `--vmodule` takes a comma-delimited list of key=value pairs. Each key is a
|
||||
// pattern matched against filenames, and the values give the effective severity
|
||||
// level applied to matching files. '?' and '*' characters in patterns are
|
||||
// interpreted as single-character and zero-or-more-character wildcards.
|
||||
// Patterns including a slash character are matched against full pathnames,
|
||||
// while those without are matched against basenames only. One suffix (i.e. the
|
||||
// last . and everything after it) is stripped from each filename prior to
|
||||
// matching, as is the special suffix "-inl".
|
||||
//
|
||||
// Example: --vmodule=module_a=1,module_b=2
|
||||
//
|
||||
// Files are matched against globs in `--vmodule` in order, and the first match
|
||||
// determines the verbosity level.
|
||||
//
|
||||
// Files which do not match any pattern in `--vmodule` use the value of `--v` as
|
||||
// their effective verbosity level. The default is 0.
|
||||
//
|
||||
// SetVLogLevel helper function is provided to do limited dynamic control over
|
||||
// V-logging by appending to `--vmodule`. Because these go at the beginning of
|
||||
// the list, they take priority over any globs previously added.
|
||||
//
|
||||
// Resetting --vmodule will override all previous modifications to `--vmodule`,
|
||||
// including via SetVLogLevel.
|
||||
|
||||
#ifndef ABSL_LOG_ABSL_VLOG_IS_ON_H_
|
||||
#define ABSL_LOG_ABSL_VLOG_IS_ON_H_
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/vlog_config.h" // IWYU pragma: export
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
// IWYU pragma: private, include "absl/log/log.h"
|
||||
|
||||
// This is expanded at the callsite to allow the compiler to optimize
|
||||
// always-false cases out of the build.
|
||||
// An ABSL_MAX_VLOG_VERBOSITY of 2 means that VLOG(3) and above should never
|
||||
// log.
|
||||
#ifdef ABSL_MAX_VLOG_VERBOSITY
|
||||
#define ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(x) \
|
||||
((x) <= ABSL_MAX_VLOG_VERBOSITY)&&
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(x)
|
||||
#endif
|
||||
|
||||
// Each ABSL_VLOG_IS_ON call site gets its own VLogSite that registers with the
|
||||
// global linked list of sites to asynchronously update its verbosity level on
|
||||
// changes to --v or --vmodule. The verbosity can also be set by manually
|
||||
// calling SetVLogLevel.
|
||||
//
|
||||
// ABSL_VLOG_IS_ON is not async signal safe, but it is guaranteed not to
|
||||
// allocate new memory.
|
||||
#define ABSL_VLOG_IS_ON(verbose_level) \
|
||||
(ABSL_LOG_INTERNAL_MAX_LOG_VERBOSITY_CHECK(verbose_level)[]() \
|
||||
->::absl::log_internal::VLogSite * \
|
||||
{ \
|
||||
ABSL_CONST_INIT static ::absl::log_internal::VLogSite site(__FILE__); \
|
||||
return &site; \
|
||||
}() \
|
||||
->IsEnabled(verbose_level))
|
||||
|
||||
#endif // ABSL_LOG_ABSL_VLOG_IS_ON_H_
|
||||
209
TMessagesProj/jni/voip/webrtc/absl/log/check.h
Normal file
209
TMessagesProj/jni/voip/webrtc/absl/log/check.h
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/check.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares a family of `CHECK` macros.
|
||||
//
|
||||
// `CHECK` macros terminate the program with a fatal error if the specified
|
||||
// condition is not true.
|
||||
//
|
||||
// Except for those whose names begin with `DCHECK`, these macros are not
|
||||
// controlled by `NDEBUG` (cf. `assert`), so the check will be executed
|
||||
// regardless of compilation mode. `CHECK` and friends are thus useful for
|
||||
// confirming invariants in situations where continuing to run would be worse
|
||||
// than terminating, e.g., due to risk of data corruption or security
|
||||
// compromise. It is also more robust and portable to deliberately terminate
|
||||
// at a particular place with a useful message and backtrace than to assume some
|
||||
// ultimately unspecified and unreliable crashing behavior (such as a
|
||||
// "segmentation fault").
|
||||
|
||||
#ifndef ABSL_LOG_CHECK_H_
|
||||
#define ABSL_LOG_CHECK_H_
|
||||
|
||||
#include "absl/log/internal/check_impl.h"
|
||||
#include "absl/log/internal/check_op.h" // IWYU pragma: export
|
||||
#include "absl/log/internal/conditions.h" // IWYU pragma: export
|
||||
#include "absl/log/internal/log_message.h" // IWYU pragma: export
|
||||
#include "absl/log/internal/strip.h" // IWYU pragma: export
|
||||
|
||||
// CHECK()
|
||||
//
|
||||
// `CHECK` terminates the program with a fatal error if `condition` is not true.
|
||||
//
|
||||
// The message may include additional information such as stack traces, when
|
||||
// available.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// CHECK(!cheese.empty()) << "Out of Cheese";
|
||||
//
|
||||
// Might produce a message like:
|
||||
//
|
||||
// Check failed: !cheese.empty() Out of Cheese
|
||||
#define CHECK(condition) ABSL_LOG_INTERNAL_CHECK_IMPL((condition), #condition)
|
||||
|
||||
// QCHECK()
|
||||
//
|
||||
// `QCHECK` behaves like `CHECK` but does not print a full stack trace and does
|
||||
// not run registered error handlers (as `QFATAL`). It is useful when the
|
||||
// problem is definitely unrelated to program flow, e.g. when validating user
|
||||
// input.
|
||||
#define QCHECK(condition) ABSL_LOG_INTERNAL_QCHECK_IMPL((condition), #condition)
|
||||
|
||||
// PCHECK()
|
||||
//
|
||||
// `PCHECK` behaves like `CHECK` but appends a description of the current state
|
||||
// of `errno` to the failure message.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// int fd = open("/var/empty/missing", O_RDONLY);
|
||||
// PCHECK(fd != -1) << "posix is difficult";
|
||||
//
|
||||
// Might produce a message like:
|
||||
//
|
||||
// Check failed: fd != -1 posix is difficult: No such file or directory [2]
|
||||
#define PCHECK(condition) ABSL_LOG_INTERNAL_PCHECK_IMPL((condition), #condition)
|
||||
|
||||
// DCHECK()
|
||||
//
|
||||
// `DCHECK` behaves like `CHECK` in debug mode and does nothing otherwise (as
|
||||
// `DLOG`). Unlike with `CHECK` (but as with `assert`), it is not safe to rely
|
||||
// on evaluation of `condition`: when `NDEBUG` is enabled, DCHECK does not
|
||||
// evaluate the condition.
|
||||
#define DCHECK(condition) ABSL_LOG_INTERNAL_DCHECK_IMPL((condition), #condition)
|
||||
|
||||
// `CHECK_EQ` and friends are syntactic sugar for `CHECK(x == y)` that
|
||||
// automatically output the expression being tested and the evaluated values on
|
||||
// either side.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// int x = 3, y = 5;
|
||||
// CHECK_EQ(2 * x, y) << "oops!";
|
||||
//
|
||||
// Might produce a message like:
|
||||
//
|
||||
// Check failed: 2 * x == y (6 vs. 5) oops!
|
||||
//
|
||||
// The values must implement the appropriate comparison operator as well as
|
||||
// `operator<<(std::ostream&, ...)`. Care is taken to ensure that each
|
||||
// argument is evaluated exactly once, and that anything which is legal to pass
|
||||
// as a function argument is legal here. In particular, the arguments may be
|
||||
// temporary expressions which will end up being destroyed at the end of the
|
||||
// statement,
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// CHECK_EQ(std::string("abc")[1], 'b');
|
||||
//
|
||||
// WARNING: Passing `NULL` as an argument to `CHECK_EQ` and similar macros does
|
||||
// not compile. Use `nullptr` instead.
|
||||
#define CHECK_EQ(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_EQ_IMPL((val1), #val1, (val2), #val2)
|
||||
#define CHECK_NE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_NE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define CHECK_LE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_LE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define CHECK_LT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_LT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define CHECK_GE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_GE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define CHECK_GT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_GT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define QCHECK_EQ(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
|
||||
#define QCHECK_NE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_NE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define QCHECK_LE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_LE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define QCHECK_LT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_LT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define QCHECK_GE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_GE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define QCHECK_GT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_GT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define DCHECK_EQ(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL((val1), #val1, (val2), #val2)
|
||||
#define DCHECK_NE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define DCHECK_LE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_LE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define DCHECK_LT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_LT_IMPL((val1), #val1, (val2), #val2)
|
||||
#define DCHECK_GE(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_GE_IMPL((val1), #val1, (val2), #val2)
|
||||
#define DCHECK_GT(val1, val2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_GT_IMPL((val1), #val1, (val2), #val2)
|
||||
|
||||
// `CHECK_OK` and friends validate that the provided `absl::Status` or
|
||||
// `absl::StatusOr<T>` is OK. If it isn't, they print a failure message that
|
||||
// includes the actual status and terminate the program.
|
||||
//
|
||||
// As with all `DCHECK` variants, `DCHECK_OK` has no effect (not even
|
||||
// evaluating its argument) if `NDEBUG` is enabled.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// CHECK_OK(FunctionReturnsStatus(x, y, z)) << "oops!";
|
||||
//
|
||||
// Might produce a message like:
|
||||
//
|
||||
// Check failed: FunctionReturnsStatus(x, y, z) is OK (ABORTED: timeout) oops!
|
||||
#define CHECK_OK(status) ABSL_LOG_INTERNAL_CHECK_OK_IMPL((status), #status)
|
||||
#define QCHECK_OK(status) ABSL_LOG_INTERNAL_QCHECK_OK_IMPL((status), #status)
|
||||
#define DCHECK_OK(status) ABSL_LOG_INTERNAL_DCHECK_OK_IMPL((status), #status)
|
||||
|
||||
// `CHECK_STREQ` and friends provide `CHECK_EQ` functionality for C strings,
|
||||
// i.e., null-terminated char arrays. The `CASE` versions are case-insensitive.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// CHECK_STREQ(argv[0], "./skynet");
|
||||
//
|
||||
// Note that both arguments may be temporary strings which are destroyed by the
|
||||
// compiler at the end of the current full expression.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// CHECK_STREQ(Foo().c_str(), Bar().c_str());
|
||||
#define CHECK_STREQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define CHECK_STRNE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define CHECK_STRCASEEQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define CHECK_STRCASENE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define QCHECK_STREQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define QCHECK_STRNE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define QCHECK_STRCASEEQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define QCHECK_STRCASENE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define DCHECK_STREQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define DCHECK_STRNE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL((s1), #s1, (s2), #s2)
|
||||
#define DCHECK_STRCASEEQ(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL((s1), #s1, (s2), #s2)
|
||||
#define DCHECK_STRCASENE(s1, s2) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL((s1), #s1, (s2), #s2)
|
||||
|
||||
#endif // ABSL_LOG_CHECK_H_
|
||||
58
TMessagesProj/jni/voip/webrtc/absl/log/check_test.cc
Normal file
58
TMessagesProj/jni/voip/webrtc/absl/log/check_test.cc
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/check.h"
|
||||
|
||||
#define ABSL_TEST_CHECK CHECK
|
||||
#define ABSL_TEST_CHECK_OK CHECK_OK
|
||||
#define ABSL_TEST_CHECK_EQ CHECK_EQ
|
||||
#define ABSL_TEST_CHECK_NE CHECK_NE
|
||||
#define ABSL_TEST_CHECK_GE CHECK_GE
|
||||
#define ABSL_TEST_CHECK_LE CHECK_LE
|
||||
#define ABSL_TEST_CHECK_GT CHECK_GT
|
||||
#define ABSL_TEST_CHECK_LT CHECK_LT
|
||||
#define ABSL_TEST_CHECK_STREQ CHECK_STREQ
|
||||
#define ABSL_TEST_CHECK_STRNE CHECK_STRNE
|
||||
#define ABSL_TEST_CHECK_STRCASEEQ CHECK_STRCASEEQ
|
||||
#define ABSL_TEST_CHECK_STRCASENE CHECK_STRCASENE
|
||||
|
||||
#define ABSL_TEST_DCHECK DCHECK
|
||||
#define ABSL_TEST_DCHECK_OK DCHECK_OK
|
||||
#define ABSL_TEST_DCHECK_EQ DCHECK_EQ
|
||||
#define ABSL_TEST_DCHECK_NE DCHECK_NE
|
||||
#define ABSL_TEST_DCHECK_GE DCHECK_GE
|
||||
#define ABSL_TEST_DCHECK_LE DCHECK_LE
|
||||
#define ABSL_TEST_DCHECK_GT DCHECK_GT
|
||||
#define ABSL_TEST_DCHECK_LT DCHECK_LT
|
||||
#define ABSL_TEST_DCHECK_STREQ DCHECK_STREQ
|
||||
#define ABSL_TEST_DCHECK_STRNE DCHECK_STRNE
|
||||
#define ABSL_TEST_DCHECK_STRCASEEQ DCHECK_STRCASEEQ
|
||||
#define ABSL_TEST_DCHECK_STRCASENE DCHECK_STRCASENE
|
||||
|
||||
#define ABSL_TEST_QCHECK QCHECK
|
||||
#define ABSL_TEST_QCHECK_OK QCHECK_OK
|
||||
#define ABSL_TEST_QCHECK_EQ QCHECK_EQ
|
||||
#define ABSL_TEST_QCHECK_NE QCHECK_NE
|
||||
#define ABSL_TEST_QCHECK_GE QCHECK_GE
|
||||
#define ABSL_TEST_QCHECK_LE QCHECK_LE
|
||||
#define ABSL_TEST_QCHECK_GT QCHECK_GT
|
||||
#define ABSL_TEST_QCHECK_LT QCHECK_LT
|
||||
#define ABSL_TEST_QCHECK_STREQ QCHECK_STREQ
|
||||
#define ABSL_TEST_QCHECK_STRNE QCHECK_STRNE
|
||||
#define ABSL_TEST_QCHECK_STRCASEEQ QCHECK_STRCASEEQ
|
||||
#define ABSL_TEST_QCHECK_STRCASENE QCHECK_STRCASENE
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/log/check_test_impl.inc"
|
||||
686
TMessagesProj/jni/voip/webrtc/absl/log/check_test_impl.inc
Normal file
686
TMessagesProj/jni/voip/webrtc/absl/log/check_test_impl.inc
Normal file
|
|
@ -0,0 +1,686 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_LOG_CHECK_TEST_IMPL_H_
|
||||
#define ABSL_LOG_CHECK_TEST_IMPL_H_
|
||||
|
||||
// Verify that both sets of macros behave identically by parameterizing the
|
||||
// entire test file.
|
||||
#ifndef ABSL_TEST_CHECK
|
||||
#error ABSL_TEST_CHECK must be defined for these tests to work.
|
||||
#endif
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/substitute.h"
|
||||
|
||||
// NOLINTBEGIN(misc-definitions-in-headers)
|
||||
|
||||
namespace absl_log_internal {
|
||||
|
||||
using ::testing::AllOf;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::Not;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKDeathTest, TestBasicValues) {
|
||||
ABSL_TEST_CHECK(true);
|
||||
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK(false), "Check failed: false");
|
||||
|
||||
int i = 2;
|
||||
ABSL_TEST_CHECK(i != 3); // NOLINT
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKTest, TestLogicExpressions) {
|
||||
int i = 5;
|
||||
ABSL_TEST_CHECK(i > 0 && i < 10);
|
||||
ABSL_TEST_CHECK(i < 0 || i > 3);
|
||||
}
|
||||
|
||||
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
ABSL_CONST_INIT const auto global_var_check = [](int i) {
|
||||
ABSL_TEST_CHECK(i > 0); // NOLINT
|
||||
return i + 1;
|
||||
}(3);
|
||||
|
||||
ABSL_CONST_INIT const auto global_var = [](int i) {
|
||||
ABSL_TEST_CHECK_GE(i, 0); // NOLINT
|
||||
return i + 1;
|
||||
}(global_var_check);
|
||||
#endif // ABSL_INTERNAL_CPLUSPLUS_LANG
|
||||
|
||||
TEST(CHECKTest, TestPlacementsInCompoundStatements) {
|
||||
// check placement inside if/else clauses
|
||||
if (true) ABSL_TEST_CHECK(true);
|
||||
|
||||
if (false)
|
||||
; // NOLINT
|
||||
else
|
||||
ABSL_TEST_CHECK(true);
|
||||
|
||||
switch (0)
|
||||
case 0:
|
||||
ABSL_TEST_CHECK(true); // NOLINT
|
||||
|
||||
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
constexpr auto var = [](int i) {
|
||||
ABSL_TEST_CHECK(i > 0); // NOLINT
|
||||
return i + 1;
|
||||
}(global_var);
|
||||
(void)var;
|
||||
#endif // ABSL_INTERNAL_CPLUSPLUS_LANG
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestBoolConvertible) {
|
||||
struct Tester {
|
||||
} tester;
|
||||
ABSL_TEST_CHECK([&]() { return &tester; }());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKDeathTest, TestChecksWithSideEffects) {
|
||||
int var = 0;
|
||||
ABSL_TEST_CHECK([&var]() {
|
||||
++var;
|
||||
return true;
|
||||
}());
|
||||
EXPECT_EQ(var, 1);
|
||||
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK([&var]() {
|
||||
++var;
|
||||
return false;
|
||||
}()) << var,
|
||||
"Check failed: .* 2");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
template <int a, int b>
|
||||
constexpr int sum() {
|
||||
return a + b;
|
||||
}
|
||||
#define MACRO_ONE 1
|
||||
#define TEMPLATE_SUM(a, b) sum<a, b>()
|
||||
#define CONCAT(a, b) a b
|
||||
#define IDENTITY(x) x
|
||||
|
||||
TEST(CHECKTest, TestPassingMacroExpansion) {
|
||||
ABSL_TEST_CHECK(IDENTITY(true));
|
||||
ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(MACRO_ONE, 2), 3);
|
||||
ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "xy");
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionInMessage) {
|
||||
auto MessageGen = []() { ABSL_TEST_CHECK(IDENTITY(false)); };
|
||||
EXPECT_DEATH(MessageGen(), HasSubstr("IDENTITY(false)"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestNestedMacroExpansionInMessage) {
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK(IDENTITY(false)), HasSubstr("IDENTITY(false)"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionCompare) {
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(IDENTITY(false), IDENTITY(true)),
|
||||
HasSubstr("IDENTITY(false) == IDENTITY(true)"));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_GT(IDENTITY(1), IDENTITY(2)),
|
||||
HasSubstr("IDENTITY(1) > IDENTITY(2)"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionStrCompare) {
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(IDENTITY("x"), IDENTITY("y")),
|
||||
HasSubstr("IDENTITY(\"x\") == IDENTITY(\"y\")"));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_STRCASENE(IDENTITY("a"), IDENTITY("A")),
|
||||
HasSubstr("IDENTITY(\"a\") != IDENTITY(\"A\")"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionStatus) {
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_OK(IDENTITY(absl::FailedPreconditionError("message"))),
|
||||
HasSubstr("IDENTITY(absl::FailedPreconditionError(\"message\"))"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionComma) {
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK(TEMPLATE_SUM(MACRO_ONE, 2) == 4),
|
||||
HasSubstr("TEMPLATE_SUM(MACRO_ONE, 2) == 4"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionCommaCompare) {
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_EQ(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)),
|
||||
HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) == TEMPLATE_SUM(3, 2)"));
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_GT(TEMPLATE_SUM(2, MACRO_ONE), TEMPLATE_SUM(3, 2)),
|
||||
HasSubstr("TEMPLATE_SUM(2, MACRO_ONE) > TEMPLATE_SUM(3, 2)"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestMacroExpansionCommaStrCompare) {
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_STREQ(CONCAT("x", "y"), "z"),
|
||||
HasSubstr("CONCAT(\"x\", \"y\") == \"z\""));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_STRNE(CONCAT("x", "y"), "xy"),
|
||||
HasSubstr("CONCAT(\"x\", \"y\") != \"xy\""));
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
#undef TEMPLATE_SUM
|
||||
#undef CONCAT
|
||||
#undef MACRO
|
||||
#undef ONE
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKDeachTest, TestOrderOfInvocationsBetweenCheckAndMessage) {
|
||||
int counter = 0;
|
||||
|
||||
auto GetStr = [&counter]() -> std::string {
|
||||
return counter++ == 0 ? "" : "non-empty";
|
||||
};
|
||||
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK(!GetStr().empty()) << GetStr(),
|
||||
HasSubstr("non-empty"));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestSecondaryFailure) {
|
||||
auto FailingRoutine = []() {
|
||||
ABSL_TEST_CHECK(false) << "Secondary";
|
||||
return false;
|
||||
};
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK(FailingRoutine()) << "Primary",
|
||||
AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary"))));
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestSecondaryFailureInMessage) {
|
||||
auto MessageGen = []() {
|
||||
ABSL_TEST_CHECK(false) << "Secondary";
|
||||
return "Primary";
|
||||
};
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK(false) << MessageGen(),
|
||||
AllOf(HasSubstr("Secondary"), Not(HasSubstr("Primary"))));
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKTest, TestBinaryChecksWithPrimitives) {
|
||||
ABSL_TEST_CHECK_EQ(1, 1);
|
||||
ABSL_TEST_CHECK_NE(1, 2);
|
||||
ABSL_TEST_CHECK_GE(1, 1);
|
||||
ABSL_TEST_CHECK_GE(2, 1);
|
||||
ABSL_TEST_CHECK_LE(1, 1);
|
||||
ABSL_TEST_CHECK_LE(1, 2);
|
||||
ABSL_TEST_CHECK_GT(2, 1);
|
||||
ABSL_TEST_CHECK_LT(1, 2);
|
||||
}
|
||||
|
||||
// For testing using CHECK*() on anonymous enums.
|
||||
enum { CASE_A, CASE_B };
|
||||
|
||||
TEST(CHECKTest, TestBinaryChecksWithEnumValues) {
|
||||
// Tests using CHECK*() on anonymous enums.
|
||||
ABSL_TEST_CHECK_EQ(CASE_A, CASE_A);
|
||||
ABSL_TEST_CHECK_NE(CASE_A, CASE_B);
|
||||
ABSL_TEST_CHECK_GE(CASE_A, CASE_A);
|
||||
ABSL_TEST_CHECK_GE(CASE_B, CASE_A);
|
||||
ABSL_TEST_CHECK_LE(CASE_A, CASE_A);
|
||||
ABSL_TEST_CHECK_LE(CASE_A, CASE_B);
|
||||
ABSL_TEST_CHECK_GT(CASE_B, CASE_A);
|
||||
ABSL_TEST_CHECK_LT(CASE_A, CASE_B);
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestBinaryChecksWithNullptr) {
|
||||
const void* p_null = nullptr;
|
||||
const void* p_not_null = &p_null;
|
||||
ABSL_TEST_CHECK_EQ(p_null, nullptr);
|
||||
ABSL_TEST_CHECK_EQ(nullptr, p_null);
|
||||
ABSL_TEST_CHECK_NE(p_not_null, nullptr);
|
||||
ABSL_TEST_CHECK_NE(nullptr, p_not_null);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
// Test logging of various char-typed values by failing CHECK*().
|
||||
TEST(CHECKDeathTest, TestComparingCharsValues) {
|
||||
{
|
||||
char a = ';';
|
||||
char b = 'b';
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(';' vs. 'b'\\)");
|
||||
b = 1;
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(';' vs. char value 1\\)");
|
||||
}
|
||||
{
|
||||
signed char a = ';';
|
||||
signed char b = 'b';
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(';' vs. 'b'\\)");
|
||||
b = -128;
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(';' vs. signed char value -128\\)");
|
||||
}
|
||||
{
|
||||
unsigned char a = ';';
|
||||
unsigned char b = 'b';
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(';' vs. 'b'\\)");
|
||||
b = 128;
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(';' vs. unsigned char value 128\\)");
|
||||
}
|
||||
}
|
||||
|
||||
TEST(CHECKDeathTest, TestNullValuesAreReportedCleanly) {
|
||||
const char* a = nullptr;
|
||||
const char* b = nullptr;
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_NE(a, b),
|
||||
"Check failed: a != b \\(\\(null\\) vs. \\(null\\)\\)");
|
||||
|
||||
a = "xx";
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(a, b),
|
||||
"Check failed: a == b \\(xx vs. \\(null\\)\\)");
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(b, a),
|
||||
"Check failed: b == a \\(\\(null\\) vs. xx\\)");
|
||||
|
||||
std::nullptr_t n{};
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_NE(n, nullptr),
|
||||
"Check failed: n != nullptr \\(\\(null\\) vs. \\(null\\)\\)");
|
||||
}
|
||||
|
||||
#endif // GTEST_HAS_DEATH_TEST
|
||||
|
||||
TEST(CHECKTest, TestSTREQ) {
|
||||
ABSL_TEST_CHECK_STREQ("this", "this");
|
||||
ABSL_TEST_CHECK_STREQ(nullptr, nullptr);
|
||||
ABSL_TEST_CHECK_STRCASEEQ("this", "tHiS");
|
||||
ABSL_TEST_CHECK_STRCASEEQ(nullptr, nullptr);
|
||||
ABSL_TEST_CHECK_STRNE("this", "tHiS");
|
||||
ABSL_TEST_CHECK_STRNE("this", nullptr);
|
||||
ABSL_TEST_CHECK_STRCASENE("this", "that");
|
||||
ABSL_TEST_CHECK_STRCASENE(nullptr, "that");
|
||||
ABSL_TEST_CHECK_STREQ((std::string("a") + "b").c_str(), "ab");
|
||||
ABSL_TEST_CHECK_STREQ(std::string("test").c_str(),
|
||||
(std::string("te") + std::string("st")).c_str());
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestComparisonPlacementsInCompoundStatements) {
|
||||
// check placement inside if/else clauses
|
||||
if (true) ABSL_TEST_CHECK_EQ(1, 1);
|
||||
if (true) ABSL_TEST_CHECK_STREQ("c", "c");
|
||||
|
||||
if (false)
|
||||
; // NOLINT
|
||||
else
|
||||
ABSL_TEST_CHECK_LE(0, 1);
|
||||
|
||||
if (false)
|
||||
; // NOLINT
|
||||
else
|
||||
ABSL_TEST_CHECK_STRNE("a", "b");
|
||||
|
||||
switch (0)
|
||||
case 0:
|
||||
ABSL_TEST_CHECK_NE(1, 0);
|
||||
|
||||
switch (0)
|
||||
case 0:
|
||||
ABSL_TEST_CHECK_STRCASEEQ("A", "a");
|
||||
|
||||
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
constexpr auto var = [](int i) {
|
||||
ABSL_TEST_CHECK_GT(i, 0);
|
||||
return i + 1;
|
||||
}(global_var);
|
||||
(void)var;
|
||||
|
||||
// CHECK_STR... checks are not supported in constexpr routines.
|
||||
// constexpr auto var2 = [](int i) {
|
||||
// ABSL_TEST_CHECK_STRNE("c", "d");
|
||||
// return i + 1;
|
||||
// }(global_var);
|
||||
|
||||
#if defined(__GNUC__)
|
||||
int var3 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0;
|
||||
(void)var3;
|
||||
|
||||
int var4 = (({ ABSL_TEST_CHECK_STREQ("a", "a"); }), global_var < 10) ? 1 : 0;
|
||||
(void)var4;
|
||||
#endif // __GNUC__
|
||||
#endif // ABSL_INTERNAL_CPLUSPLUS_LANG
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestDCHECK) {
|
||||
#ifdef NDEBUG
|
||||
ABSL_TEST_DCHECK(1 == 2) << " DCHECK's shouldn't be compiled in normal mode";
|
||||
#endif
|
||||
ABSL_TEST_DCHECK(1 == 1); // NOLINT(readability/check)
|
||||
ABSL_TEST_DCHECK_EQ(1, 1);
|
||||
ABSL_TEST_DCHECK_NE(1, 2);
|
||||
ABSL_TEST_DCHECK_GE(1, 1);
|
||||
ABSL_TEST_DCHECK_GE(2, 1);
|
||||
ABSL_TEST_DCHECK_LE(1, 1);
|
||||
ABSL_TEST_DCHECK_LE(1, 2);
|
||||
ABSL_TEST_DCHECK_GT(2, 1);
|
||||
ABSL_TEST_DCHECK_LT(1, 2);
|
||||
|
||||
// Test DCHECK on std::nullptr_t
|
||||
const void* p_null = nullptr;
|
||||
const void* p_not_null = &p_null;
|
||||
ABSL_TEST_DCHECK_EQ(p_null, nullptr);
|
||||
ABSL_TEST_DCHECK_EQ(nullptr, p_null);
|
||||
ABSL_TEST_DCHECK_NE(p_not_null, nullptr);
|
||||
ABSL_TEST_DCHECK_NE(nullptr, p_not_null);
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestQCHECK) {
|
||||
// The tests that QCHECK does the same as CHECK
|
||||
ABSL_TEST_QCHECK(1 == 1); // NOLINT(readability/check)
|
||||
ABSL_TEST_QCHECK_EQ(1, 1);
|
||||
ABSL_TEST_QCHECK_NE(1, 2);
|
||||
ABSL_TEST_QCHECK_GE(1, 1);
|
||||
ABSL_TEST_QCHECK_GE(2, 1);
|
||||
ABSL_TEST_QCHECK_LE(1, 1);
|
||||
ABSL_TEST_QCHECK_LE(1, 2);
|
||||
ABSL_TEST_QCHECK_GT(2, 1);
|
||||
ABSL_TEST_QCHECK_LT(1, 2);
|
||||
|
||||
// Tests using QCHECK*() on anonymous enums.
|
||||
ABSL_TEST_QCHECK_EQ(CASE_A, CASE_A);
|
||||
ABSL_TEST_QCHECK_NE(CASE_A, CASE_B);
|
||||
ABSL_TEST_QCHECK_GE(CASE_A, CASE_A);
|
||||
ABSL_TEST_QCHECK_GE(CASE_B, CASE_A);
|
||||
ABSL_TEST_QCHECK_LE(CASE_A, CASE_A);
|
||||
ABSL_TEST_QCHECK_LE(CASE_A, CASE_B);
|
||||
ABSL_TEST_QCHECK_GT(CASE_B, CASE_A);
|
||||
ABSL_TEST_QCHECK_LT(CASE_A, CASE_B);
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestQCHECKPlacementsInCompoundStatements) {
|
||||
// check placement inside if/else clauses
|
||||
if (true) ABSL_TEST_QCHECK(true);
|
||||
|
||||
if (false)
|
||||
; // NOLINT
|
||||
else
|
||||
ABSL_TEST_QCHECK(true);
|
||||
|
||||
if (false)
|
||||
; // NOLINT
|
||||
else
|
||||
ABSL_TEST_QCHECK(true);
|
||||
|
||||
switch (0)
|
||||
case 0:
|
||||
ABSL_TEST_QCHECK(true);
|
||||
|
||||
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 201703L
|
||||
constexpr auto var = [](int i) {
|
||||
ABSL_TEST_QCHECK(i > 0); // NOLINT
|
||||
return i + 1;
|
||||
}(global_var);
|
||||
(void)var;
|
||||
|
||||
#if defined(__GNUC__)
|
||||
int var2 = (({ ABSL_TEST_CHECK_LE(1, 2); }), global_var < 10) ? 1 : 0;
|
||||
(void)var2;
|
||||
#endif // __GNUC__
|
||||
#endif // ABSL_INTERNAL_CPLUSPLUS_LANG
|
||||
}
|
||||
|
||||
class ComparableType {
|
||||
public:
|
||||
explicit ComparableType(int v) : v_(v) {}
|
||||
|
||||
void MethodWithCheck(int i) {
|
||||
ABSL_TEST_CHECK_EQ(*this, i);
|
||||
ABSL_TEST_CHECK_EQ(i, *this);
|
||||
}
|
||||
|
||||
int Get() const { return v_; }
|
||||
|
||||
private:
|
||||
friend bool operator==(const ComparableType& lhs, const ComparableType& rhs) {
|
||||
return lhs.v_ == rhs.v_;
|
||||
}
|
||||
friend bool operator!=(const ComparableType& lhs, const ComparableType& rhs) {
|
||||
return lhs.v_ != rhs.v_;
|
||||
}
|
||||
friend bool operator<(const ComparableType& lhs, const ComparableType& rhs) {
|
||||
return lhs.v_ < rhs.v_;
|
||||
}
|
||||
friend bool operator<=(const ComparableType& lhs, const ComparableType& rhs) {
|
||||
return lhs.v_ <= rhs.v_;
|
||||
}
|
||||
friend bool operator>(const ComparableType& lhs, const ComparableType& rhs) {
|
||||
return lhs.v_ > rhs.v_;
|
||||
}
|
||||
friend bool operator>=(const ComparableType& lhs, const ComparableType& rhs) {
|
||||
return lhs.v_ >= rhs.v_;
|
||||
}
|
||||
friend bool operator==(const ComparableType& lhs, int rhs) {
|
||||
return lhs.v_ == rhs;
|
||||
}
|
||||
friend bool operator==(int lhs, const ComparableType& rhs) {
|
||||
return lhs == rhs.v_;
|
||||
}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& out, const ComparableType& v) {
|
||||
return out << "ComparableType{" << v.Get() << "}";
|
||||
}
|
||||
|
||||
int v_;
|
||||
};
|
||||
|
||||
TEST(CHECKTest, TestUserDefinedCompOp) {
|
||||
ABSL_TEST_CHECK_EQ(ComparableType{0}, ComparableType{0});
|
||||
ABSL_TEST_CHECK_NE(ComparableType{1}, ComparableType{2});
|
||||
ABSL_TEST_CHECK_LT(ComparableType{1}, ComparableType{2});
|
||||
ABSL_TEST_CHECK_LE(ComparableType{1}, ComparableType{2});
|
||||
ABSL_TEST_CHECK_GT(ComparableType{2}, ComparableType{1});
|
||||
ABSL_TEST_CHECK_GE(ComparableType{2}, ComparableType{2});
|
||||
}
|
||||
|
||||
TEST(CHECKTest, TestCheckInMethod) {
|
||||
ComparableType v{1};
|
||||
v.MethodWithCheck(1);
|
||||
}
|
||||
|
||||
TEST(CHECKDeathTest, TestUserDefinedStreaming) {
|
||||
ComparableType v1{1};
|
||||
ComparableType v2{2};
|
||||
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_EQ(v1, v2),
|
||||
HasSubstr(
|
||||
"Check failed: v1 == v2 (ComparableType{1} vs. ComparableType{2})"));
|
||||
}
|
||||
|
||||
// A type that can be printed using AbslStringify.
|
||||
struct StringifiableType {
|
||||
int x = 0;
|
||||
explicit StringifiableType(int x) : x(x) {}
|
||||
friend bool operator==(const StringifiableType& lhs,
|
||||
const StringifiableType& rhs) {
|
||||
return lhs.x == rhs.x;
|
||||
}
|
||||
friend bool operator!=(const StringifiableType& lhs,
|
||||
const StringifiableType& rhs) {
|
||||
return lhs.x != rhs.x;
|
||||
}
|
||||
friend bool operator<(const StringifiableType& lhs,
|
||||
const StringifiableType& rhs) {
|
||||
return lhs.x < rhs.x;
|
||||
}
|
||||
friend bool operator>(const StringifiableType& lhs,
|
||||
const StringifiableType& rhs) {
|
||||
return lhs.x > rhs.x;
|
||||
}
|
||||
friend bool operator<=(const StringifiableType& lhs,
|
||||
const StringifiableType& rhs) {
|
||||
return lhs.x <= rhs.x;
|
||||
}
|
||||
friend bool operator>=(const StringifiableType& lhs,
|
||||
const StringifiableType& rhs) {
|
||||
return lhs.x >= rhs.x;
|
||||
}
|
||||
template <typename Sink>
|
||||
friend void AbslStringify(Sink& sink, const StringifiableType& obj) {
|
||||
absl::Format(&sink, "StringifiableType{%d}", obj.x);
|
||||
}
|
||||
|
||||
// Make sure no unintended copy happens.
|
||||
StringifiableType(const StringifiableType&) = delete;
|
||||
};
|
||||
|
||||
TEST(CHECKTest, TestUserDefinedAbslStringify) {
|
||||
const StringifiableType v1(1);
|
||||
const StringifiableType v2(2);
|
||||
|
||||
ABSL_TEST_CHECK_EQ(v1, v1);
|
||||
ABSL_TEST_CHECK_NE(v1, v2);
|
||||
ABSL_TEST_CHECK_LT(v1, v2);
|
||||
ABSL_TEST_CHECK_LE(v1, v2);
|
||||
ABSL_TEST_CHECK_GT(v2, v1);
|
||||
ABSL_TEST_CHECK_GE(v2, v1);
|
||||
}
|
||||
|
||||
TEST(CHECKDeathTest, TestUserDefinedAbslStringify) {
|
||||
const StringifiableType v1(1);
|
||||
const StringifiableType v2(2);
|
||||
|
||||
// Returns a matcher for the expected check failure message when comparing two
|
||||
// values.
|
||||
auto expected_output = [](int lhs, absl::string_view condition, int rhs) {
|
||||
return HasSubstr(
|
||||
absl::Substitute("Check failed: v$0 $1 v$2 (StringifiableType{$0} vs. "
|
||||
"StringifiableType{$2})",
|
||||
lhs, condition, rhs));
|
||||
};
|
||||
// Test comparisons where the check fails.
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(v1, v2), expected_output(1, "==", 2));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_NE(v1, v1), expected_output(1, "!=", 1));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_LT(v2, v1), expected_output(2, "<", 1));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_LE(v2, v1), expected_output(2, "<=", 1));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_GT(v1, v2), expected_output(1, ">", 2));
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_GE(v1, v2), expected_output(1, ">=", 2));
|
||||
}
|
||||
|
||||
// A type that can be printed using both AbslStringify and operator<<.
|
||||
struct StringifiableStreamableType {
|
||||
int x = 0;
|
||||
explicit StringifiableStreamableType(int x) : x(x) {}
|
||||
|
||||
friend bool operator==(const StringifiableStreamableType& lhs,
|
||||
const StringifiableStreamableType& rhs) {
|
||||
return lhs.x == rhs.x;
|
||||
}
|
||||
friend bool operator!=(const StringifiableStreamableType& lhs,
|
||||
const StringifiableStreamableType& rhs) {
|
||||
return lhs.x != rhs.x;
|
||||
}
|
||||
template <typename Sink>
|
||||
friend void AbslStringify(Sink& sink,
|
||||
const StringifiableStreamableType& obj) {
|
||||
absl::Format(&sink, "Strigified{%d}", obj.x);
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& out,
|
||||
const StringifiableStreamableType& obj) {
|
||||
return out << "Streamed{" << obj.x << "}";
|
||||
}
|
||||
|
||||
// Avoid unintentional copy.
|
||||
StringifiableStreamableType(const StringifiableStreamableType&) = delete;
|
||||
};
|
||||
|
||||
TEST(CHECKDeathTest, TestStreamingPreferredOverAbslStringify) {
|
||||
StringifiableStreamableType v1(1);
|
||||
StringifiableStreamableType v2(2);
|
||||
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_EQ(v1, v2),
|
||||
HasSubstr("Check failed: v1 == v2 (Streamed{1} vs. Streamed{2})"));
|
||||
}
|
||||
|
||||
// A type whose pointer can be passed to AbslStringify.
|
||||
struct PointerIsStringifiable {};
|
||||
template <typename Sink>
|
||||
void AbslStringify(Sink& sink, const PointerIsStringifiable* var) {
|
||||
sink.Append("PointerIsStringifiable");
|
||||
}
|
||||
|
||||
// Verifies that a pointer is printed as a number despite having AbslStringify
|
||||
// defined. Users may implement AbslStringify that dereferences the pointer, and
|
||||
// doing so as part of DCHECK would not be good.
|
||||
TEST(CHECKDeathTest, TestPointerPrintedAsNumberDespiteAbslStringify) {
|
||||
const auto* p = reinterpret_cast<const PointerIsStringifiable*>(0x1234);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_EQ(p, nullptr),
|
||||
HasSubstr("Check failed: p == nullptr (0000000000001234 vs. (null))"));
|
||||
#else // _MSC_VER
|
||||
EXPECT_DEATH(ABSL_TEST_CHECK_EQ(p, nullptr),
|
||||
HasSubstr("Check failed: p == nullptr (0x1234 vs. (null))"));
|
||||
#endif // _MSC_VER
|
||||
}
|
||||
|
||||
// An uncopyable object with operator<<.
|
||||
struct Uncopyable {
|
||||
int x;
|
||||
explicit Uncopyable(int x) : x(x) {}
|
||||
Uncopyable(const Uncopyable&) = delete;
|
||||
friend bool operator==(const Uncopyable& lhs, const Uncopyable& rhs) {
|
||||
return lhs.x == rhs.x;
|
||||
}
|
||||
friend bool operator!=(const Uncopyable& lhs, const Uncopyable& rhs) {
|
||||
return lhs.x != rhs.x;
|
||||
}
|
||||
friend std::ostream& operator<<(std::ostream& os, const Uncopyable& obj) {
|
||||
return os << "Uncopyable{" << obj.x << "}";
|
||||
}
|
||||
};
|
||||
|
||||
// Test that an uncopyable object can be used.
|
||||
// Will catch us if implementation has an unintended copy.
|
||||
TEST(CHECKDeathTest, TestUncopyable) {
|
||||
const Uncopyable v1(1);
|
||||
const Uncopyable v2(2);
|
||||
|
||||
EXPECT_DEATH(
|
||||
ABSL_TEST_CHECK_EQ(v1, v2),
|
||||
HasSubstr("Check failed: v1 == v2 (Uncopyable{1} vs. Uncopyable{2})"));
|
||||
}
|
||||
|
||||
} // namespace absl_log_internal
|
||||
|
||||
// NOLINTEND(misc-definitions-in-headers)
|
||||
|
||||
#endif // ABSL_LOG_CHECK_TEST_IMPL_H_
|
||||
32
TMessagesProj/jni/voip/webrtc/absl/log/die_if_null.cc
Normal file
32
TMessagesProj/jni/voip/webrtc/absl/log/die_if_null.cc
Normal file
|
|
@ -0,0 +1,32 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/die_if_null.h"
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
void DieBecauseNull(const char* file, int line, const char* exprtext) {
|
||||
LOG(FATAL).AtLocation(file, line)
|
||||
<< absl::StrCat("Check failed: '", exprtext, "' Must be non-null");
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
76
TMessagesProj/jni/voip/webrtc/absl/log/die_if_null.h
Normal file
76
TMessagesProj/jni/voip/webrtc/absl/log/die_if_null.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/die_if_null.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares macro `ABSL_DIE_IF_NULL`.
|
||||
|
||||
#ifndef ABSL_LOG_DIE_IF_NULL_H_
|
||||
#define ABSL_LOG_DIE_IF_NULL_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/optimization.h"
|
||||
|
||||
// ABSL_DIE_IF_NULL()
|
||||
//
|
||||
// `ABSL_DIE_IF_NULL` behaves as `CHECK_NE` against `nullptr` but *also*
|
||||
// "returns" its argument. It is useful in initializers where statements (like
|
||||
// `CHECK_NE`) can't be used. Outside initializers, prefer `CHECK` or
|
||||
// `CHECK_NE`. `ABSL_DIE_IF_NULL` works for both raw pointers and (compatible)
|
||||
// smart pointers including `std::unique_ptr` and `std::shared_ptr`; more
|
||||
// generally, it works for any type that can be compared to nullptr_t. For
|
||||
// types that aren't raw pointers, `ABSL_DIE_IF_NULL` returns a reference to
|
||||
// its argument, preserving the value category. Example:
|
||||
//
|
||||
// Foo() : bar_(ABSL_DIE_IF_NULL(MethodReturningUniquePtr())) {}
|
||||
//
|
||||
// Use `CHECK(ptr)` or `CHECK(ptr != nullptr)` if the returned pointer is
|
||||
// unused.
|
||||
#define ABSL_DIE_IF_NULL(val) \
|
||||
::absl::log_internal::DieIfNull(__FILE__, __LINE__, #val, (val))
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// Crashes the process after logging `exprtext` annotated at the `file` and
|
||||
// `line` location. Called when `ABSL_DIE_IF_NULL` fails. Calling this function
|
||||
// generates less code than its implementation would if inlined, for a slight
|
||||
// code size reduction each time `ABSL_DIE_IF_NULL` is called.
|
||||
[[noreturn]] ABSL_ATTRIBUTE_NOINLINE void DieBecauseNull(
|
||||
const char* file, int line, const char* exprtext);
|
||||
|
||||
// Helper for `ABSL_DIE_IF_NULL`.
|
||||
template <typename T>
|
||||
ABSL_MUST_USE_RESULT T DieIfNull(const char* file, int line,
|
||||
const char* exprtext, T&& t) {
|
||||
if (ABSL_PREDICT_FALSE(t == nullptr)) {
|
||||
// Call a non-inline helper function for a small code size improvement.
|
||||
DieBecauseNull(file, line, exprtext);
|
||||
}
|
||||
return std::forward<T>(t);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_DIE_IF_NULL_H_
|
||||
107
TMessagesProj/jni/voip/webrtc/absl/log/die_if_null_test.cc
Normal file
107
TMessagesProj/jni/voip/webrtc/absl/log/die_if_null_test.cc
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/die_if_null.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
|
||||
namespace {
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
// TODO(b/69907837): Revisit these tests with the goal of making them less
|
||||
// convoluted.
|
||||
TEST(AbslDieIfNull, Simple) {
|
||||
int64_t t;
|
||||
void* ptr = static_cast<void*>(&t);
|
||||
void* ref = ABSL_DIE_IF_NULL(ptr);
|
||||
ASSERT_EQ(ptr, ref);
|
||||
|
||||
char* t_as_char;
|
||||
t_as_char = ABSL_DIE_IF_NULL(reinterpret_cast<char*>(&t));
|
||||
(void)t_as_char;
|
||||
|
||||
unsigned char* t_as_uchar;
|
||||
t_as_uchar = ABSL_DIE_IF_NULL(reinterpret_cast<unsigned char*>(&t));
|
||||
(void)t_as_uchar;
|
||||
|
||||
int* t_as_int;
|
||||
t_as_int = ABSL_DIE_IF_NULL(reinterpret_cast<int*>(&t));
|
||||
(void)t_as_int;
|
||||
|
||||
int64_t* t_as_int64_t;
|
||||
t_as_int64_t = ABSL_DIE_IF_NULL(reinterpret_cast<int64_t*>(&t));
|
||||
(void)t_as_int64_t;
|
||||
|
||||
std::unique_ptr<int64_t> sptr(new int64_t);
|
||||
EXPECT_EQ(sptr.get(), ABSL_DIE_IF_NULL(sptr).get());
|
||||
ABSL_DIE_IF_NULL(sptr).reset();
|
||||
|
||||
int64_t* int_ptr = new int64_t();
|
||||
EXPECT_EQ(int_ptr, ABSL_DIE_IF_NULL(std::unique_ptr<int64_t>(int_ptr)).get());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(DeathCheckAbslDieIfNull, Simple) {
|
||||
void* ptr;
|
||||
ASSERT_DEATH({ ptr = ABSL_DIE_IF_NULL(nullptr); }, "");
|
||||
(void)ptr;
|
||||
|
||||
std::unique_ptr<int64_t> sptr;
|
||||
ASSERT_DEATH(ptr = ABSL_DIE_IF_NULL(sptr).get(), "");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Ensures that ABSL_DIE_IF_NULL works with C++11's std::unique_ptr and
|
||||
// std::shared_ptr.
|
||||
TEST(AbslDieIfNull, DoesNotCompareSmartPointerToNULL) {
|
||||
std::unique_ptr<int> up(new int);
|
||||
EXPECT_EQ(&up, &ABSL_DIE_IF_NULL(up));
|
||||
ABSL_DIE_IF_NULL(up).reset();
|
||||
|
||||
std::shared_ptr<int> sp(new int);
|
||||
EXPECT_EQ(&sp, &ABSL_DIE_IF_NULL(sp));
|
||||
ABSL_DIE_IF_NULL(sp).reset();
|
||||
}
|
||||
|
||||
// Verifies that ABSL_DIE_IF_NULL returns an rvalue reference if its argument is
|
||||
// an rvalue reference.
|
||||
TEST(AbslDieIfNull, PreservesRValues) {
|
||||
int64_t* ptr = new int64_t();
|
||||
auto uptr = ABSL_DIE_IF_NULL(std::unique_ptr<int64_t>(ptr));
|
||||
EXPECT_EQ(ptr, uptr.get());
|
||||
}
|
||||
|
||||
// Verifies that ABSL_DIE_IF_NULL returns an lvalue if its argument is an
|
||||
// lvalue.
|
||||
TEST(AbslDieIfNull, PreservesLValues) {
|
||||
int64_t array[2] = {0};
|
||||
int64_t* a = array + 0;
|
||||
int64_t* b = array + 1;
|
||||
using std::swap;
|
||||
swap(ABSL_DIE_IF_NULL(a), ABSL_DIE_IF_NULL(b));
|
||||
EXPECT_EQ(array + 1, a);
|
||||
EXPECT_EQ(array + 0, b);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
143
TMessagesProj/jni/voip/webrtc/absl/log/flags.cc
Normal file
143
TMessagesProj/jni/voip/webrtc/absl/log/flags.cc
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/flags.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/marshalling.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/config.h"
|
||||
#include "absl/log/internal/vlog_config.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
|
||||
void SyncLoggingFlags() {
|
||||
absl::SetFlag(&FLAGS_minloglevel, static_cast<int>(absl::MinLogLevel()));
|
||||
absl::SetFlag(&FLAGS_log_prefix, absl::ShouldPrependLogPrefix());
|
||||
}
|
||||
|
||||
bool RegisterSyncLoggingFlags() {
|
||||
log_internal::SetLoggingGlobalsListener(&SyncLoggingFlags);
|
||||
return true;
|
||||
}
|
||||
|
||||
ABSL_ATTRIBUTE_UNUSED const bool unused = RegisterSyncLoggingFlags();
|
||||
|
||||
template <typename T>
|
||||
T GetFromEnv(const char* varname, T dflt) {
|
||||
const char* val = ::getenv(varname);
|
||||
if (val != nullptr) {
|
||||
std::string err;
|
||||
ABSL_INTERNAL_CHECK(absl::ParseFlag(val, &dflt, &err), err.c_str());
|
||||
}
|
||||
return dflt;
|
||||
}
|
||||
|
||||
constexpr absl::LogSeverityAtLeast StderrThresholdDefault() {
|
||||
return absl::LogSeverityAtLeast::kError;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
ABSL_FLAG(int, stderrthreshold,
|
||||
static_cast<int>(absl::log_internal::StderrThresholdDefault()),
|
||||
"Log messages at or above this threshold level are copied to stderr.")
|
||||
.OnUpdate([] {
|
||||
absl::log_internal::RawSetStderrThreshold(
|
||||
static_cast<absl::LogSeverityAtLeast>(
|
||||
absl::GetFlag(FLAGS_stderrthreshold)));
|
||||
});
|
||||
|
||||
ABSL_FLAG(int, minloglevel, static_cast<int>(absl::LogSeverityAtLeast::kInfo),
|
||||
"Messages logged at a lower level than this don't actually "
|
||||
"get logged anywhere")
|
||||
.OnUpdate([] {
|
||||
absl::log_internal::RawSetMinLogLevel(
|
||||
static_cast<absl::LogSeverityAtLeast>(
|
||||
absl::GetFlag(FLAGS_minloglevel)));
|
||||
});
|
||||
|
||||
ABSL_FLAG(std::string, log_backtrace_at, "",
|
||||
"Emit a backtrace when logging at file:linenum.")
|
||||
.OnUpdate([] {
|
||||
const std::string log_backtrace_at =
|
||||
absl::GetFlag(FLAGS_log_backtrace_at);
|
||||
if (log_backtrace_at.empty()) {
|
||||
absl::ClearLogBacktraceLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
const size_t last_colon = log_backtrace_at.rfind(':');
|
||||
if (last_colon == log_backtrace_at.npos) {
|
||||
absl::ClearLogBacktraceLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
const absl::string_view file =
|
||||
absl::string_view(log_backtrace_at).substr(0, last_colon);
|
||||
int line;
|
||||
if (!absl::SimpleAtoi(
|
||||
absl::string_view(log_backtrace_at).substr(last_colon + 1),
|
||||
&line)) {
|
||||
absl::ClearLogBacktraceLocation();
|
||||
return;
|
||||
}
|
||||
absl::SetLogBacktraceLocation(file, line);
|
||||
});
|
||||
|
||||
ABSL_FLAG(bool, log_prefix, true,
|
||||
"Prepend the log prefix to the start of each log line")
|
||||
.OnUpdate([] {
|
||||
absl::log_internal::RawEnableLogPrefix(absl::GetFlag(FLAGS_log_prefix));
|
||||
});
|
||||
|
||||
ABSL_FLAG(int, v, 0,
|
||||
"Show all VLOG(m) messages for m <= this. Overridable by --vmodule.")
|
||||
.OnUpdate([] {
|
||||
absl::log_internal::UpdateGlobalVLogLevel(absl::GetFlag(FLAGS_v));
|
||||
});
|
||||
|
||||
ABSL_FLAG(
|
||||
std::string, vmodule, "",
|
||||
"per-module log verbosity level."
|
||||
" Argument is a comma-separated list of <module name>=<log level>."
|
||||
" <module name> is a glob pattern, matched against the filename base"
|
||||
" (that is, name ignoring .cc/.h./-inl.h)."
|
||||
" A pattern without slashes matches just the file name portion, otherwise"
|
||||
" the whole file path below the workspace root"
|
||||
" (still without .cc/.h./-inl.h) is matched."
|
||||
" ? and * in the glob pattern match any single or sequence of characters"
|
||||
" respectively including slashes."
|
||||
" <log level> overrides any value given by --v.")
|
||||
.OnUpdate([] {
|
||||
absl::log_internal::UpdateVModule(absl::GetFlag(FLAGS_vmodule));
|
||||
});
|
||||
43
TMessagesProj/jni/voip/webrtc/absl/log/flags.h
Normal file
43
TMessagesProj/jni/voip/webrtc/absl/log/flags.h
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/flags.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef ABSL_LOG_FLAGS_H_
|
||||
#define ABSL_LOG_FLAGS_H_
|
||||
|
||||
// The Abseil Logging library supports the following command line flags to
|
||||
// configure logging behavior at runtime:
|
||||
//
|
||||
// --stderrthreshold=<value>
|
||||
// Log messages at or above this threshold level are copied to stderr.
|
||||
//
|
||||
// --minloglevel=<value>
|
||||
// Messages logged at a lower level than this are discarded and don't actually
|
||||
// get logged anywhere.
|
||||
//
|
||||
// --log_backtrace_at=<file:linenum>
|
||||
// Emit a backtrace (stack trace) when logging at file:linenum.
|
||||
//
|
||||
// To use these commandline flags, the //absl/log:flags library must be
|
||||
// explicitly linked, and absl::ParseCommandLine() must be called before the
|
||||
// call to absl::InitializeLog().
|
||||
//
|
||||
// To configure the Log library programmatically, use the interfaces defined in
|
||||
// absl/log/globals.h.
|
||||
|
||||
#endif // ABSL_LOG_FLAGS_H_
|
||||
188
TMessagesProj/jni/voip/webrtc/absl/log/flags_test.cc
Normal file
188
TMessagesProj/jni/voip/webrtc/absl/log/flags_test.cc
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/flags.h"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/flags/reflection.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
|
||||
namespace {
|
||||
using ::absl::log_internal::TextMessage;
|
||||
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::Not;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
constexpr static absl::LogSeverityAtLeast DefaultStderrThreshold() {
|
||||
return absl::LogSeverityAtLeast::kError;
|
||||
}
|
||||
|
||||
class LogFlagsTest : public ::testing::Test {
|
||||
protected:
|
||||
absl::FlagSaver flag_saver_;
|
||||
};
|
||||
|
||||
// This test is disabled because it adds order dependency to the test suite.
|
||||
// This order dependency is currently not fixable due to the way the
|
||||
// stderrthreshold global value is out of sync with the stderrthreshold flag.
|
||||
TEST_F(LogFlagsTest, DISABLED_StderrKnobsDefault) {
|
||||
EXPECT_EQ(absl::StderrThreshold(), DefaultStderrThreshold());
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, SetStderrThreshold) {
|
||||
absl::SetFlag(&FLAGS_stderrthreshold,
|
||||
static_cast<int>(absl::LogSeverityAtLeast::kInfo));
|
||||
|
||||
EXPECT_EQ(absl::StderrThreshold(), absl::LogSeverityAtLeast::kInfo);
|
||||
|
||||
absl::SetFlag(&FLAGS_stderrthreshold,
|
||||
static_cast<int>(absl::LogSeverityAtLeast::kError));
|
||||
|
||||
EXPECT_EQ(absl::StderrThreshold(), absl::LogSeverityAtLeast::kError);
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, SetMinLogLevel) {
|
||||
absl::SetFlag(&FLAGS_minloglevel,
|
||||
static_cast<int>(absl::LogSeverityAtLeast::kError));
|
||||
|
||||
EXPECT_EQ(absl::MinLogLevel(), absl::LogSeverityAtLeast::kError);
|
||||
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(
|
||||
absl::LogSeverityAtLeast::kWarning);
|
||||
|
||||
EXPECT_EQ(absl::GetFlag(FLAGS_minloglevel),
|
||||
static_cast<int>(absl::LogSeverityAtLeast::kWarning));
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, PrependLogPrefix) {
|
||||
absl::SetFlag(&FLAGS_log_prefix, false);
|
||||
|
||||
EXPECT_EQ(absl::ShouldPrependLogPrefix(), false);
|
||||
|
||||
absl::EnableLogPrefix(true);
|
||||
|
||||
EXPECT_EQ(absl::GetFlag(FLAGS_log_prefix), true);
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, EmptyBacktraceAtFlag) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at, "");
|
||||
LOG(INFO) << "hello world";
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, BacktraceAtNonsense) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at, "gibberish");
|
||||
LOG(INFO) << "hello world";
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, BacktraceAtWrongFile) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { LOG(INFO) << "hello world"; };
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at,
|
||||
absl::StrCat("some_other_file.cc:", log_line));
|
||||
do_log();
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, BacktraceAtWrongLine) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { LOG(INFO) << "hello world"; };
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at,
|
||||
absl::StrCat("flags_test.cc:", log_line + 1));
|
||||
do_log();
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, BacktraceAtWholeFilename) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { LOG(INFO) << "hello world"; };
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at, absl::StrCat(__FILE__, ":", log_line));
|
||||
do_log();
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, BacktraceAtNonmatchingSuffix) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { LOG(INFO) << "hello world"; };
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at,
|
||||
absl::StrCat("flags_test.cc:", log_line, "gibberish"));
|
||||
do_log();
|
||||
}
|
||||
|
||||
TEST_F(LogFlagsTest, LogsBacktrace) {
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfo);
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { LOG(INFO) << "hello world"; };
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
testing::InSequence seq;
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(HasSubstr("(stacktrace:"))));
|
||||
EXPECT_CALL(test_sink, Send(TextMessage(Not(HasSubstr("(stacktrace:")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at,
|
||||
absl::StrCat("flags_test.cc:", log_line));
|
||||
do_log();
|
||||
absl::SetFlag(&FLAGS_log_backtrace_at, "");
|
||||
do_log();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
178
TMessagesProj/jni/voip/webrtc/absl/log/globals.cc
Normal file
178
TMessagesProj/jni/voip/webrtc/absl/log/globals.cc
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/globals.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/atomic_hook.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/hash/hash.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace {
|
||||
|
||||
// These atomics represent logging library configuration.
|
||||
// Integer types are used instead of absl::LogSeverity to ensure that a
|
||||
// lock-free std::atomic is used when possible.
|
||||
ABSL_CONST_INIT std::atomic<int> min_log_level{
|
||||
static_cast<int>(absl::LogSeverityAtLeast::kInfo)};
|
||||
ABSL_CONST_INIT std::atomic<int> stderrthreshold{
|
||||
static_cast<int>(absl::LogSeverityAtLeast::kError)};
|
||||
// We evaluate this value as a hash comparison to avoid having to
|
||||
// hold a mutex or make a copy (to access the value of a string-typed flag) in
|
||||
// very hot codepath.
|
||||
ABSL_CONST_INIT std::atomic<size_t> log_backtrace_at_hash{0};
|
||||
ABSL_CONST_INIT std::atomic<bool> prepend_log_prefix{true};
|
||||
|
||||
constexpr char kDefaultAndroidTag[] = "native";
|
||||
ABSL_CONST_INIT std::atomic<const char*> android_log_tag{kDefaultAndroidTag};
|
||||
|
||||
ABSL_INTERNAL_ATOMIC_HOOK_ATTRIBUTES
|
||||
absl::base_internal::AtomicHook<log_internal::LoggingGlobalsListener>
|
||||
logging_globals_listener;
|
||||
|
||||
size_t HashSiteForLogBacktraceAt(absl::string_view file, int line) {
|
||||
return absl::HashOf(file, line);
|
||||
}
|
||||
|
||||
void TriggerLoggingGlobalsListener() {
|
||||
auto* listener = logging_globals_listener.Load();
|
||||
if (listener != nullptr) listener();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
void RawSetMinLogLevel(absl::LogSeverityAtLeast severity) {
|
||||
min_log_level.store(static_cast<int>(severity), std::memory_order_release);
|
||||
}
|
||||
|
||||
void RawSetStderrThreshold(absl::LogSeverityAtLeast severity) {
|
||||
stderrthreshold.store(static_cast<int>(severity), std::memory_order_release);
|
||||
}
|
||||
|
||||
void RawEnableLogPrefix(bool on_off) {
|
||||
prepend_log_prefix.store(on_off, std::memory_order_release);
|
||||
}
|
||||
|
||||
void SetLoggingGlobalsListener(LoggingGlobalsListener l) {
|
||||
logging_globals_listener.Store(l);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
absl::LogSeverityAtLeast MinLogLevel() {
|
||||
return static_cast<absl::LogSeverityAtLeast>(
|
||||
min_log_level.load(std::memory_order_acquire));
|
||||
}
|
||||
|
||||
void SetMinLogLevel(absl::LogSeverityAtLeast severity) {
|
||||
log_internal::RawSetMinLogLevel(severity);
|
||||
TriggerLoggingGlobalsListener();
|
||||
}
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
ScopedMinLogLevel::ScopedMinLogLevel(absl::LogSeverityAtLeast severity)
|
||||
: saved_severity_(absl::MinLogLevel()) {
|
||||
absl::SetMinLogLevel(severity);
|
||||
}
|
||||
ScopedMinLogLevel::~ScopedMinLogLevel() {
|
||||
absl::SetMinLogLevel(saved_severity_);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
absl::LogSeverityAtLeast StderrThreshold() {
|
||||
return static_cast<absl::LogSeverityAtLeast>(
|
||||
stderrthreshold.load(std::memory_order_acquire));
|
||||
}
|
||||
|
||||
void SetStderrThreshold(absl::LogSeverityAtLeast severity) {
|
||||
log_internal::RawSetStderrThreshold(severity);
|
||||
TriggerLoggingGlobalsListener();
|
||||
}
|
||||
|
||||
ScopedStderrThreshold::ScopedStderrThreshold(absl::LogSeverityAtLeast severity)
|
||||
: saved_severity_(absl::StderrThreshold()) {
|
||||
absl::SetStderrThreshold(severity);
|
||||
}
|
||||
|
||||
ScopedStderrThreshold::~ScopedStderrThreshold() {
|
||||
absl::SetStderrThreshold(saved_severity_);
|
||||
}
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
const char* GetAndroidNativeTag() {
|
||||
return android_log_tag.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
void SetAndroidNativeTag(const char* tag) {
|
||||
ABSL_CONST_INIT static std::atomic<const std::string*> user_log_tag(nullptr);
|
||||
ABSL_INTERNAL_CHECK(tag, "tag must be non-null.");
|
||||
|
||||
const std::string* tag_str = new std::string(tag);
|
||||
ABSL_INTERNAL_CHECK(
|
||||
android_log_tag.exchange(tag_str->c_str(), std::memory_order_acq_rel) ==
|
||||
kDefaultAndroidTag,
|
||||
"SetAndroidNativeTag() must only be called once per process!");
|
||||
user_log_tag.store(tag_str, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
bool ShouldLogBacktraceAt(absl::string_view file, int line) {
|
||||
const size_t flag_hash =
|
||||
log_backtrace_at_hash.load(std::memory_order_relaxed);
|
||||
|
||||
return flag_hash != 0 && flag_hash == HashSiteForLogBacktraceAt(file, line);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
void SetLogBacktraceLocation(absl::string_view file, int line) {
|
||||
log_backtrace_at_hash.store(HashSiteForLogBacktraceAt(file, line),
|
||||
std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
void ClearLogBacktraceLocation() {
|
||||
log_backtrace_at_hash.store(0, std::memory_order_relaxed);
|
||||
}
|
||||
|
||||
bool ShouldPrependLogPrefix() {
|
||||
return prepend_log_prefix.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void EnableLogPrefix(bool on_off) {
|
||||
log_internal::RawEnableLogPrefix(on_off);
|
||||
TriggerLoggingGlobalsListener();
|
||||
}
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
231
TMessagesProj/jni/voip/webrtc/absl/log/globals.h
Normal file
231
TMessagesProj/jni/voip/webrtc/absl/log/globals.h
Normal file
|
|
@ -0,0 +1,231 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/globals.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares global logging library configuration knobs.
|
||||
|
||||
#ifndef ABSL_LOG_GLOBALS_H_
|
||||
#define ABSL_LOG_GLOBALS_H_
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/vlog_config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Minimum Log Level
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Messages logged at or above this severity are directed to all registered log
|
||||
// sinks or skipped otherwise. This parameter can also be modified using
|
||||
// command line flag --minloglevel.
|
||||
// See absl/base/log_severity.h for descriptions of severity levels.
|
||||
|
||||
// MinLogLevel()
|
||||
//
|
||||
// Returns the value of the Minimum Log Level parameter.
|
||||
// This function is async-signal-safe.
|
||||
ABSL_MUST_USE_RESULT absl::LogSeverityAtLeast MinLogLevel();
|
||||
|
||||
// SetMinLogLevel()
|
||||
//
|
||||
// Updates the value of Minimum Log Level parameter.
|
||||
// This function is async-signal-safe.
|
||||
void SetMinLogLevel(absl::LogSeverityAtLeast severity);
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
// ScopedMinLogLevel
|
||||
//
|
||||
// RAII type used to temporarily update the Min Log Level parameter.
|
||||
class ScopedMinLogLevel final {
|
||||
public:
|
||||
explicit ScopedMinLogLevel(absl::LogSeverityAtLeast severity);
|
||||
ScopedMinLogLevel(const ScopedMinLogLevel&) = delete;
|
||||
ScopedMinLogLevel& operator=(const ScopedMinLogLevel&) = delete;
|
||||
~ScopedMinLogLevel();
|
||||
|
||||
private:
|
||||
absl::LogSeverityAtLeast saved_severity_;
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Stderr Threshold
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Messages logged at or above this level are directed to stderr in
|
||||
// addition to other registered log sinks. This parameter can also be modified
|
||||
// using command line flag --stderrthreshold.
|
||||
// See absl/base/log_severity.h for descriptions of severity levels.
|
||||
|
||||
// StderrThreshold()
|
||||
//
|
||||
// Returns the value of the Stderr Threshold parameter.
|
||||
// This function is async-signal-safe.
|
||||
ABSL_MUST_USE_RESULT absl::LogSeverityAtLeast StderrThreshold();
|
||||
|
||||
// SetStderrThreshold()
|
||||
//
|
||||
// Updates the Stderr Threshold parameter.
|
||||
// This function is async-signal-safe.
|
||||
void SetStderrThreshold(absl::LogSeverityAtLeast severity);
|
||||
inline void SetStderrThreshold(absl::LogSeverity severity) {
|
||||
absl::SetStderrThreshold(static_cast<absl::LogSeverityAtLeast>(severity));
|
||||
}
|
||||
|
||||
// ScopedStderrThreshold
|
||||
//
|
||||
// RAII type used to temporarily update the Stderr Threshold parameter.
|
||||
class ScopedStderrThreshold final {
|
||||
public:
|
||||
explicit ScopedStderrThreshold(absl::LogSeverityAtLeast severity);
|
||||
ScopedStderrThreshold(const ScopedStderrThreshold&) = delete;
|
||||
ScopedStderrThreshold& operator=(const ScopedStderrThreshold&) = delete;
|
||||
~ScopedStderrThreshold();
|
||||
|
||||
private:
|
||||
absl::LogSeverityAtLeast saved_severity_;
|
||||
};
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Log Backtrace At
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// Users can request an existing `LOG` statement, specified by file and line
|
||||
// number, to also include a backtrace when logged.
|
||||
|
||||
// ShouldLogBacktraceAt()
|
||||
//
|
||||
// Returns true if we should log a backtrace at the specified location.
|
||||
namespace log_internal {
|
||||
ABSL_MUST_USE_RESULT bool ShouldLogBacktraceAt(absl::string_view file,
|
||||
int line);
|
||||
} // namespace log_internal
|
||||
|
||||
// SetLogBacktraceLocation()
|
||||
//
|
||||
// Sets the location the backtrace should be logged at. If the specified
|
||||
// location isn't a `LOG` statement, the effect will be the same as
|
||||
// `ClearLogBacktraceLocation` (but less efficient).
|
||||
void SetLogBacktraceLocation(absl::string_view file, int line);
|
||||
|
||||
// ClearLogBacktraceLocation()
|
||||
//
|
||||
// Clears the set location so that backtraces will no longer be logged at it.
|
||||
void ClearLogBacktraceLocation();
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Prepend Log Prefix
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// This option tells the logging library that every logged message
|
||||
// should include the prefix (severity, date, time, PID, etc.)
|
||||
//
|
||||
// ShouldPrependLogPrefix()
|
||||
//
|
||||
// Returns the value of the Prepend Log Prefix option.
|
||||
// This function is async-signal-safe.
|
||||
ABSL_MUST_USE_RESULT bool ShouldPrependLogPrefix();
|
||||
|
||||
// EnableLogPrefix()
|
||||
//
|
||||
// Updates the value of the Prepend Log Prefix option.
|
||||
// This function is async-signal-safe.
|
||||
void EnableLogPrefix(bool on_off);
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// `VLOG` Configuration
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// These methods set the `(ABSL_)VLOG(_IS_ON)` threshold. They allow
|
||||
// programmatic control of the thresholds set by the --v and --vmodule flags.
|
||||
//
|
||||
// Only `VLOG`s with a severity level LESS THAN OR EQUAL TO the threshold will
|
||||
// be evaluated.
|
||||
//
|
||||
// For example, if the threshold is 2, then:
|
||||
//
|
||||
// VLOG(2) << "This message will be logged.";
|
||||
// VLOG(3) << "This message will NOT be logged.";
|
||||
//
|
||||
// The default threshold is 0. Since `VLOG` levels must not be negative, a
|
||||
// negative threshold value will turn off all VLOGs.
|
||||
|
||||
// SetGlobalVLogLevel()
|
||||
//
|
||||
// Sets the global `VLOG` level to threshold. Returns the previous global
|
||||
// threshold.
|
||||
inline int SetGlobalVLogLevel(int threshold) {
|
||||
return absl::log_internal::UpdateGlobalVLogLevel(threshold);
|
||||
}
|
||||
|
||||
// SetVLogLevel()
|
||||
//
|
||||
// Sets the `VLOG` threshold for all files that match `module_pattern`,
|
||||
// overwriting any prior value. Files that don't match aren't affected.
|
||||
// Returns the threshold that previously applied to `module_pattern`.
|
||||
inline int SetVLogLevel(absl::string_view module_pattern, int threshold) {
|
||||
return absl::log_internal::PrependVModule(module_pattern, threshold);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Configure Android Native Log Tag
|
||||
//------------------------------------------------------------------------------
|
||||
//
|
||||
// The logging library forwards to the Android system log API when built for
|
||||
// Android. That API takes a string "tag" value in addition to a message and
|
||||
// severity level. The tag is used to identify the source of messages and to
|
||||
// filter them. This library uses the tag "native" by default.
|
||||
|
||||
// SetAndroidNativeTag()
|
||||
//
|
||||
// Stores a copy of the string pointed to by `tag` and uses it as the Android
|
||||
// logging tag thereafter. `tag` must not be null.
|
||||
// This function must not be called more than once!
|
||||
void SetAndroidNativeTag(const char* tag);
|
||||
|
||||
namespace log_internal {
|
||||
// GetAndroidNativeTag()
|
||||
//
|
||||
// Returns the configured Android logging tag.
|
||||
const char* GetAndroidNativeTag();
|
||||
} // namespace log_internal
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
using LoggingGlobalsListener = void (*)();
|
||||
void SetLoggingGlobalsListener(LoggingGlobalsListener l);
|
||||
|
||||
// Internal implementation for the setter routines. These are used
|
||||
// to break circular dependencies between flags and globals. Each "Raw"
|
||||
// routine corresponds to the non-"Raw" counterpart and used to set the
|
||||
// configuration parameter directly without calling back to the listener.
|
||||
void RawSetMinLogLevel(absl::LogSeverityAtLeast severity);
|
||||
void RawSetStderrThreshold(absl::LogSeverityAtLeast severity);
|
||||
void RawEnableLogPrefix(bool on_off);
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_GLOBALS_H_
|
||||
156
TMessagesProj/jni/voip/webrtc/absl/log/globals_test.cc
Normal file
156
TMessagesProj/jni/voip/webrtc/absl/log/globals_test.cc
Normal file
|
|
@ -0,0 +1,156 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/globals.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
|
||||
namespace {
|
||||
using ::testing::_;
|
||||
using ::testing::StrEq;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
constexpr static absl::LogSeverityAtLeast DefaultMinLogLevel() {
|
||||
return absl::LogSeverityAtLeast::kInfo;
|
||||
}
|
||||
constexpr static absl::LogSeverityAtLeast DefaultStderrThreshold() {
|
||||
return absl::LogSeverityAtLeast::kError;
|
||||
}
|
||||
|
||||
TEST(TestGlobals, MinLogLevel) {
|
||||
EXPECT_EQ(absl::MinLogLevel(), DefaultMinLogLevel());
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kError);
|
||||
EXPECT_EQ(absl::MinLogLevel(), absl::LogSeverityAtLeast::kError);
|
||||
absl::SetMinLogLevel(DefaultMinLogLevel());
|
||||
}
|
||||
|
||||
TEST(TestGlobals, ScopedMinLogLevel) {
|
||||
EXPECT_EQ(absl::MinLogLevel(), DefaultMinLogLevel());
|
||||
{
|
||||
absl::log_internal::ScopedMinLogLevel scoped_stderr_threshold(
|
||||
absl::LogSeverityAtLeast::kError);
|
||||
EXPECT_EQ(absl::MinLogLevel(), absl::LogSeverityAtLeast::kError);
|
||||
}
|
||||
EXPECT_EQ(absl::MinLogLevel(), DefaultMinLogLevel());
|
||||
}
|
||||
|
||||
TEST(TestGlobals, StderrThreshold) {
|
||||
EXPECT_EQ(absl::StderrThreshold(), DefaultStderrThreshold());
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kError);
|
||||
EXPECT_EQ(absl::StderrThreshold(), absl::LogSeverityAtLeast::kError);
|
||||
absl::SetStderrThreshold(DefaultStderrThreshold());
|
||||
}
|
||||
|
||||
TEST(TestGlobals, ScopedStderrThreshold) {
|
||||
EXPECT_EQ(absl::StderrThreshold(), DefaultStderrThreshold());
|
||||
{
|
||||
absl::ScopedStderrThreshold scoped_stderr_threshold(
|
||||
absl::LogSeverityAtLeast::kError);
|
||||
EXPECT_EQ(absl::StderrThreshold(), absl::LogSeverityAtLeast::kError);
|
||||
}
|
||||
EXPECT_EQ(absl::StderrThreshold(), DefaultStderrThreshold());
|
||||
}
|
||||
|
||||
TEST(TestGlobals, LogBacktraceAt) {
|
||||
EXPECT_FALSE(absl::log_internal::ShouldLogBacktraceAt("some_file.cc", 111));
|
||||
absl::SetLogBacktraceLocation("some_file.cc", 111);
|
||||
EXPECT_TRUE(absl::log_internal::ShouldLogBacktraceAt("some_file.cc", 111));
|
||||
EXPECT_FALSE(
|
||||
absl::log_internal::ShouldLogBacktraceAt("another_file.cc", 222));
|
||||
}
|
||||
|
||||
TEST(TestGlobals, LogPrefix) {
|
||||
EXPECT_TRUE(absl::ShouldPrependLogPrefix());
|
||||
absl::EnableLogPrefix(false);
|
||||
EXPECT_FALSE(absl::ShouldPrependLogPrefix());
|
||||
absl::EnableLogPrefix(true);
|
||||
EXPECT_TRUE(absl::ShouldPrependLogPrefix());
|
||||
}
|
||||
|
||||
TEST(TestGlobals, SetGlobalVLogLevel) {
|
||||
EXPECT_EQ(absl::SetGlobalVLogLevel(42), 0);
|
||||
EXPECT_EQ(absl::SetGlobalVLogLevel(1337), 42);
|
||||
// Restore the value since it affects the default unset module value for
|
||||
// `SetVLogLevel()`.
|
||||
EXPECT_EQ(absl::SetGlobalVLogLevel(0), 1337);
|
||||
}
|
||||
|
||||
TEST(TestGlobals, SetVLogLevel) {
|
||||
EXPECT_EQ(absl::SetVLogLevel("setvloglevel", 42), 0);
|
||||
EXPECT_EQ(absl::SetVLogLevel("setvloglevel", 1337), 42);
|
||||
EXPECT_EQ(absl::SetVLogLevel("othersetvloglevel", 50), 0);
|
||||
|
||||
EXPECT_EQ(absl::SetVLogLevel("*pattern*", 1), 0);
|
||||
EXPECT_EQ(absl::SetVLogLevel("*less_generic_pattern*", 2), 1);
|
||||
// "pattern_match" matches the pattern "*pattern*". Therefore, the previous
|
||||
// level must be 1.
|
||||
EXPECT_EQ(absl::SetVLogLevel("pattern_match", 3), 1);
|
||||
// "less_generic_pattern_match" matches the pattern "*pattern*". Therefore,
|
||||
// the previous level must be 2.
|
||||
EXPECT_EQ(absl::SetVLogLevel("less_generic_pattern_match", 4), 2);
|
||||
}
|
||||
|
||||
TEST(TestGlobals, AndroidLogTag) {
|
||||
// Verify invalid tags result in a check failure.
|
||||
EXPECT_DEATH_IF_SUPPORTED(absl::SetAndroidNativeTag(nullptr), ".*");
|
||||
|
||||
// Verify valid tags applied.
|
||||
EXPECT_THAT(absl::log_internal::GetAndroidNativeTag(), StrEq("native"));
|
||||
absl::SetAndroidNativeTag("test_tag");
|
||||
EXPECT_THAT(absl::log_internal::GetAndroidNativeTag(), StrEq("test_tag"));
|
||||
|
||||
// Verify that additional calls (more than 1) result in a check failure.
|
||||
EXPECT_DEATH_IF_SUPPORTED(absl::SetAndroidNativeTag("test_tag_fail"), ".*");
|
||||
}
|
||||
|
||||
TEST(TestExitOnDFatal, OffTest) {
|
||||
// Turn off...
|
||||
absl::log_internal::SetExitOnDFatal(false);
|
||||
EXPECT_FALSE(absl::log_internal::ExitOnDFatal());
|
||||
|
||||
// We don't die.
|
||||
{
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
// LOG(DFATAL) has severity FATAL if debugging, but is
|
||||
// downgraded to ERROR if not debugging.
|
||||
EXPECT_CALL(log, Log(absl::kLogDebugFatal, _, "This should not be fatal"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
LOG(DFATAL) << "This should not be fatal";
|
||||
}
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(TestDeathWhileExitOnDFatal, OnTest) {
|
||||
absl::log_internal::SetExitOnDFatal(true);
|
||||
EXPECT_TRUE(absl::log_internal::ExitOnDFatal());
|
||||
|
||||
// Death comes on little cats' feet.
|
||||
EXPECT_DEBUG_DEATH({ LOG(DFATAL) << "This should be fatal in debug mode"; },
|
||||
"This should be fatal in debug mode");
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
38
TMessagesProj/jni/voip/webrtc/absl/log/initialize.cc
Normal file
38
TMessagesProj/jni/voip/webrtc/absl/log/initialize.cc
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/initialize.h"
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
namespace {
|
||||
void InitializeLogImpl(absl::TimeZone time_zone) {
|
||||
// This comes first since it is used by RAW_LOG.
|
||||
absl::log_internal::SetTimeZone(time_zone);
|
||||
|
||||
// Note that initialization is complete, so logs can now be sent to their
|
||||
// proper destinations rather than stderr.
|
||||
log_internal::SetInitialized();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
void InitializeLog() { InitializeLogImpl(absl::LocalTimeZone()); }
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
45
TMessagesProj/jni/voip/webrtc/absl/log/initialize.h
Normal file
45
TMessagesProj/jni/voip/webrtc/absl/log/initialize.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/initialize.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares the Abseil Log initialization routine InitializeLog().
|
||||
|
||||
#ifndef ABSL_LOG_INITIALIZE_H_
|
||||
#define ABSL_LOG_INITIALIZE_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// InitializeLog()
|
||||
//
|
||||
// Initializes the Abseil logging library.
|
||||
//
|
||||
// Before this function is called, all log messages are directed only to stderr.
|
||||
// After initialization is finished, log messages are directed to all registered
|
||||
// `LogSink`s.
|
||||
//
|
||||
// It is an error to call this function twice.
|
||||
//
|
||||
// There is no corresponding function to shut down the logging library.
|
||||
void InitializeLog();
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INITIALIZE_H_
|
||||
547
TMessagesProj/jni/voip/webrtc/absl/log/internal/BUILD.bazel
Normal file
547
TMessagesProj/jni/voip/webrtc/absl/log/internal/BUILD.bazel
Normal file
|
|
@ -0,0 +1,547 @@
|
|||
#
|
||||
# Copyright 2022 The Abseil Authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
load(
|
||||
"//absl:copts/configure_copts.bzl",
|
||||
"ABSL_DEFAULT_COPTS",
|
||||
"ABSL_DEFAULT_LINKOPTS",
|
||||
"ABSL_TEST_COPTS",
|
||||
)
|
||||
|
||||
package(
|
||||
default_visibility = [
|
||||
":internal_users",
|
||||
],
|
||||
features = [
|
||||
"header_modules",
|
||||
"layering_check",
|
||||
"parse_headers",
|
||||
],
|
||||
)
|
||||
|
||||
licenses(["notice"])
|
||||
|
||||
package_group(
|
||||
name = "internal_users",
|
||||
packages = [
|
||||
"//absl/log",
|
||||
],
|
||||
)
|
||||
|
||||
package_group(
|
||||
name = "structured_proto_users",
|
||||
packages = [
|
||||
"//absl/log/...",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "check_impl",
|
||||
hdrs = ["check_impl.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":check_op",
|
||||
":conditions",
|
||||
":log_message",
|
||||
":strip",
|
||||
"//absl/base:core_headers",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "check_op",
|
||||
srcs = ["check_op.cc"],
|
||||
hdrs = ["check_op.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
"//absl/log:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":nullguard",
|
||||
":nullstream",
|
||||
":strip",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:nullability",
|
||||
"//absl/debugging:leak_check",
|
||||
"//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "conditions",
|
||||
srcs = ["conditions.cc"],
|
||||
hdrs = ["conditions.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":voidify",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "config",
|
||||
hdrs = ["config.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
"//absl/log:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "flags",
|
||||
hdrs = ["flags.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/flags:flag",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "format",
|
||||
srcs = ["log_format.cc"],
|
||||
hdrs = ["log_format.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":append_truncated",
|
||||
":config",
|
||||
":globals",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/strings",
|
||||
"//absl/strings:str_format",
|
||||
"//absl/time",
|
||||
"//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "globals",
|
||||
srcs = ["globals.cc"],
|
||||
hdrs = ["globals.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
"//absl/log:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "log_impl",
|
||||
hdrs = ["log_impl.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":conditions",
|
||||
":log_message",
|
||||
":strip",
|
||||
"//absl/log:absl_vlog_is_on",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "log_message",
|
||||
srcs = ["log_message.cc"],
|
||||
hdrs = ["log_message.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
"//absl/log:__pkg__",
|
||||
],
|
||||
deps = [
|
||||
":append_truncated",
|
||||
":format",
|
||||
":globals",
|
||||
":log_sink_set",
|
||||
":nullguard",
|
||||
":proto",
|
||||
":structured_proto",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:errno_saver",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/base:nullability",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/base:strerror",
|
||||
"//absl/container:inlined_vector",
|
||||
"//absl/debugging:examine_stack",
|
||||
"//absl/log:globals",
|
||||
"//absl/log:log_entry",
|
||||
"//absl/log:log_sink",
|
||||
"//absl/log:log_sink_registry",
|
||||
"//absl/memory",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
"//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "append_truncated",
|
||||
hdrs = ["append_truncated.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/strings",
|
||||
"//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "log_sink_set",
|
||||
srcs = ["log_sink_set.cc"],
|
||||
hdrs = ["log_sink_set.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS + select({
|
||||
"//conditions:default": [],
|
||||
"@platforms//os:android": ["-llog"],
|
||||
}),
|
||||
deps = [
|
||||
":config",
|
||||
":globals",
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/base:no_destructor",
|
||||
"//absl/base:raw_logging_internal",
|
||||
"//absl/cleanup",
|
||||
"//absl/log:globals",
|
||||
"//absl/log:log_entry",
|
||||
"//absl/log:log_sink",
|
||||
"//absl/strings",
|
||||
"//absl/synchronization",
|
||||
"//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "nullguard",
|
||||
srcs = ["nullguard.cc"],
|
||||
hdrs = ["nullguard.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "nullstream",
|
||||
hdrs = ["nullstream.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "strip",
|
||||
hdrs = ["strip.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":log_message",
|
||||
":nullstream",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "structured",
|
||||
hdrs = ["structured.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
":internal_users",
|
||||
":structured_proto_users",
|
||||
],
|
||||
deps = [
|
||||
":log_message",
|
||||
":structured_proto",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/functional:any_invocable",
|
||||
"//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "structured_proto",
|
||||
srcs = ["structured_proto.cc"],
|
||||
hdrs = ["structured_proto.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
":structured_proto_users",
|
||||
],
|
||||
deps = [
|
||||
":proto",
|
||||
"//absl/base:config",
|
||||
"//absl/strings",
|
||||
"//absl/types:span",
|
||||
"//absl/types:variant",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "structured_proto_test",
|
||||
srcs = ["structured_proto_test.cc"],
|
||||
deps = [
|
||||
":structured_proto",
|
||||
"//absl/base:config",
|
||||
"//absl/strings:string_view",
|
||||
"//absl/types:span",
|
||||
"//absl/utility",
|
||||
"@googletest//:gtest",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "test_actions",
|
||||
testonly = True,
|
||||
srcs = ["test_actions.cc"],
|
||||
hdrs = ["test_actions.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/log:log_entry",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
] + select({
|
||||
"@rules_cc//cc/compiler:msvc-cl": [],
|
||||
"//conditions:default": [
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "test_helpers",
|
||||
testonly = True,
|
||||
srcs = ["test_helpers.cc"],
|
||||
hdrs = ["test_helpers.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
":internal_users",
|
||||
":structured_proto_users",
|
||||
],
|
||||
deps = [
|
||||
":globals",
|
||||
"//absl/base:config",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/log:globals",
|
||||
"//absl/log:initialize",
|
||||
"@googletest//:gtest",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "test_matchers",
|
||||
testonly = True,
|
||||
srcs = ["test_matchers.cc"],
|
||||
hdrs = ["test_matchers.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
":internal_users",
|
||||
":structured_proto_users",
|
||||
],
|
||||
deps = [
|
||||
":test_helpers",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/log:log_entry",
|
||||
"//absl/strings",
|
||||
"//absl/time",
|
||||
"@googletest//:gtest",
|
||||
] + select({
|
||||
"@rules_cc//cc/compiler:msvc-cl": [],
|
||||
"//conditions:default": [
|
||||
],
|
||||
}),
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "voidify",
|
||||
hdrs = ["voidify.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = ["//absl/base:config"],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "proto",
|
||||
srcs = ["proto.cc"],
|
||||
hdrs = ["proto.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
":internal_users",
|
||||
":structured_proto_users",
|
||||
],
|
||||
deps = [
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/strings",
|
||||
"//absl/types:span",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "fnmatch",
|
||||
srcs = ["fnmatch.cc"],
|
||||
hdrs = ["fnmatch.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
"//absl/base:config",
|
||||
"//absl/strings",
|
||||
],
|
||||
)
|
||||
|
||||
cc_library(
|
||||
name = "vlog_config",
|
||||
srcs = ["vlog_config.cc"],
|
||||
hdrs = ["vlog_config.h"],
|
||||
copts = ABSL_DEFAULT_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
visibility = [
|
||||
"//absl/log:__subpackages__",
|
||||
],
|
||||
deps = [
|
||||
"//absl/base",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:no_destructor",
|
||||
"//absl/log/internal:fnmatch",
|
||||
"//absl/memory",
|
||||
"//absl/strings",
|
||||
"//absl/synchronization",
|
||||
"//absl/types:optional",
|
||||
],
|
||||
)
|
||||
|
||||
cc_binary(
|
||||
name = "vlog_config_benchmark",
|
||||
testonly = True,
|
||||
srcs = ["vlog_config_benchmark.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
tags = [
|
||||
"benchmark",
|
||||
],
|
||||
visibility = ["//visibility:private"],
|
||||
deps = [
|
||||
":vlog_config",
|
||||
"//absl/base:config",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/container:layout",
|
||||
"//absl/memory",
|
||||
"//absl/random:distributions",
|
||||
"//absl/strings",
|
||||
"@google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
||||
# Test targets
|
||||
cc_test(
|
||||
name = "stderr_log_sink_test",
|
||||
size = "small",
|
||||
timeout = "moderate",
|
||||
srcs = ["stderr_log_sink_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
tags = [
|
||||
"no_test:os:android",
|
||||
"no_test:os:ios",
|
||||
"no_test_android",
|
||||
"no_test_darwin_arm64",
|
||||
"no_test_darwin_x86_64",
|
||||
"no_test_fuchsia_x64",
|
||||
"no_test_ios",
|
||||
"no_test_wasm",
|
||||
],
|
||||
deps = [
|
||||
":test_helpers",
|
||||
"//absl/base:core_headers",
|
||||
"//absl/base:log_severity",
|
||||
"//absl/log",
|
||||
"//absl/log:globals",
|
||||
"@googletest//:gtest",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "fnmatch_test",
|
||||
srcs = ["fnmatch_test.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
deps = [
|
||||
":fnmatch",
|
||||
"@googletest//:gtest",
|
||||
"@googletest//:gtest_main",
|
||||
],
|
||||
)
|
||||
|
||||
cc_test(
|
||||
name = "fnmatch_benchmark",
|
||||
srcs = ["fnmatch_benchmark.cc"],
|
||||
copts = ABSL_TEST_COPTS,
|
||||
linkopts = ABSL_DEFAULT_LINKOPTS,
|
||||
tags = ["benchmark"],
|
||||
deps = [
|
||||
":fnmatch",
|
||||
"@google_benchmark//:benchmark_main",
|
||||
],
|
||||
)
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
// Copyright 2022 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_APPEND_TRUNCATED_H_
|
||||
#define ABSL_LOG_INTERNAL_APPEND_TRUNCATED_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
// Copies into `dst` as many bytes of `src` as will fit, then truncates the
|
||||
// copied bytes from the front of `dst` and returns the number of bytes written.
|
||||
inline size_t AppendTruncated(absl::string_view src, absl::Span<char> &dst) {
|
||||
if (src.size() > dst.size()) src = src.substr(0, dst.size());
|
||||
memcpy(dst.data(), src.data(), src.size());
|
||||
dst.remove_prefix(src.size());
|
||||
return src.size();
|
||||
}
|
||||
// Likewise, but `n` copies of `c`.
|
||||
inline size_t AppendTruncated(char c, size_t n, absl::Span<char> &dst) {
|
||||
if (n > dst.size()) n = dst.size();
|
||||
memset(dst.data(), c, n);
|
||||
dst.remove_prefix(n);
|
||||
return n;
|
||||
}
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_APPEND_TRUNCATED_H_
|
||||
150
TMessagesProj/jni/voip/webrtc/absl/log/internal/check_impl.h
Normal file
150
TMessagesProj/jni/voip/webrtc/absl/log/internal/check_impl.h
Normal file
|
|
@ -0,0 +1,150 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_CHECK_IMPL_H_
|
||||
#define ABSL_LOG_INTERNAL_CHECK_IMPL_H_
|
||||
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/log/internal/check_op.h"
|
||||
#include "absl/log/internal/conditions.h"
|
||||
#include "absl/log/internal/log_message.h"
|
||||
#include "absl/log/internal/strip.h"
|
||||
|
||||
// CHECK
|
||||
#define ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, \
|
||||
ABSL_PREDICT_FALSE(!(condition))) \
|
||||
ABSL_LOG_INTERNAL_CHECK(condition_text).InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_IMPL(condition, condition_text) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, \
|
||||
ABSL_PREDICT_FALSE(!(condition))) \
|
||||
ABSL_LOG_INTERNAL_QCHECK(condition_text).InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PCHECK_IMPL(condition, condition_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text).WithPerror()
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_IMPL(condition, condition_text)
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_IMPL(condition, condition_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_IMPL(true || (condition), "true")
|
||||
#endif
|
||||
|
||||
// CHECK_EQ
|
||||
#define ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OP(Check_EQ, ==, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OP(Check_NE, !=, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OP(Check_LE, <=, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OP(Check_LT, <, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OP(Check_GE, >=, val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OP(Check_GT, >, val1, val1_text, val2, val2_text)
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_EQ_IMPL(val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_NE_IMPL(val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_LE_IMPL(val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_LT_IMPL(val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_GE_IMPL(val1, val1_text, val2, val2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_GT_IMPL(val1, val1_text, val2, val2_text)
|
||||
#else // ndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_EQ_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_NE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_LE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_LT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_GE_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_GT_IMPL(val1, val1_text, val2, val2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(val1, val2)
|
||||
#endif // def NDEBUG
|
||||
|
||||
// CHECK_OK
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OK_IMPL(status, status_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OK(status, status_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_OK_IMPL(status, status_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_OK(status, status_text)
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_OK(status, status_text)
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_OK_IMPL(status, status_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(status, nullptr)
|
||||
#endif
|
||||
|
||||
// CHECK_STREQ
|
||||
#define ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, ==, true, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STROP(strcmp, !=, false, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, ==, true, s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_QCHECK_STROP(strcasecmp, !=, false, s1, s1_text, s2, \
|
||||
s2_text)
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STREQ_IMPL(s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRNE_IMPL(s1, s1_text, s2, s2_text)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_CHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text)
|
||||
#else // ndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STREQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STRCASEEQ_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STRNE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_STRCASENE_IMPL(s1, s1_text, s2, s2_text) \
|
||||
ABSL_LOG_INTERNAL_DCHECK_NOP(s1, s2)
|
||||
#endif // def NDEBUG
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_CHECK_IMPL_H_
|
||||
143
TMessagesProj/jni/voip/webrtc/absl/log/internal/check_op.cc
Normal file
143
TMessagesProj/jni/voip/webrtc/absl/log/internal/check_op.cc
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/check_op.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/debugging/leak_check.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include <strings.h> // for strcasecmp, but msvc does not have this header
|
||||
#endif
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(x) \
|
||||
template absl::Nonnull<const char*> MakeCheckOpString( \
|
||||
x, x, absl::Nonnull<const char*>)
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(bool);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(int64_t);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(uint64_t);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(float);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(double);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(char);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(unsigned char);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const std::string&);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const absl::string_view&);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const char*);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const signed char*);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const unsigned char*);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*);
|
||||
#undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING
|
||||
|
||||
CheckOpMessageBuilder::CheckOpMessageBuilder(
|
||||
absl::Nonnull<const char*> exprtext) {
|
||||
stream_ << exprtext << " (";
|
||||
}
|
||||
|
||||
std::ostream& CheckOpMessageBuilder::ForVar2() {
|
||||
stream_ << " vs. ";
|
||||
return stream_;
|
||||
}
|
||||
|
||||
absl::Nonnull<const char*> CheckOpMessageBuilder::NewString() {
|
||||
stream_ << ")";
|
||||
// There's no need to free this string since the process is crashing.
|
||||
return absl::IgnoreLeak(new std::string(std::move(stream_).str()))->c_str();
|
||||
}
|
||||
|
||||
void MakeCheckOpValueString(std::ostream& os, const char v) {
|
||||
if (v >= 32 && v <= 126) {
|
||||
os << "'" << v << "'";
|
||||
} else {
|
||||
os << "char value " << int{v};
|
||||
}
|
||||
}
|
||||
|
||||
void MakeCheckOpValueString(std::ostream& os, const signed char v) {
|
||||
if (v >= 32 && v <= 126) {
|
||||
os << "'" << v << "'";
|
||||
} else {
|
||||
os << "signed char value " << int{v};
|
||||
}
|
||||
}
|
||||
|
||||
void MakeCheckOpValueString(std::ostream& os, const unsigned char v) {
|
||||
if (v >= 32 && v <= 126) {
|
||||
os << "'" << v << "'";
|
||||
} else {
|
||||
os << "unsigned char value " << int{v};
|
||||
}
|
||||
}
|
||||
|
||||
void MakeCheckOpValueString(std::ostream& os, const void* p) {
|
||||
if (p == nullptr) {
|
||||
os << "(null)";
|
||||
} else {
|
||||
os << p;
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions for string comparisons.
|
||||
#define DEFINE_CHECK_STROP_IMPL(name, func, expected) \
|
||||
absl::Nullable<const char*> Check##func##expected##Impl( \
|
||||
absl::Nullable<const char*> s1, absl::Nullable<const char*> s2, \
|
||||
absl::Nonnull<const char*> exprtext) { \
|
||||
bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
|
||||
if (equal == expected) { \
|
||||
return nullptr; \
|
||||
} else { \
|
||||
/* There's no need to free this string since the process is crashing. */ \
|
||||
return absl::IgnoreLeak(new std::string(absl::StrCat(exprtext, " (", s1, \
|
||||
" vs. ", s2, ")"))) \
|
||||
->c_str(); \
|
||||
} \
|
||||
}
|
||||
DEFINE_CHECK_STROP_IMPL(CHECK_STREQ, strcmp, true)
|
||||
DEFINE_CHECK_STROP_IMPL(CHECK_STRNE, strcmp, false)
|
||||
DEFINE_CHECK_STROP_IMPL(CHECK_STRCASEEQ, strcasecmp, true)
|
||||
DEFINE_CHECK_STROP_IMPL(CHECK_STRCASENE, strcasecmp, false)
|
||||
#undef DEFINE_CHECK_STROP_IMPL
|
||||
|
||||
namespace detect_specialization {
|
||||
|
||||
StringifySink::StringifySink(std::ostream& os) : os_(os) {}
|
||||
|
||||
void StringifySink::Append(absl::string_view text) { os_ << text; }
|
||||
|
||||
void StringifySink::Append(size_t length, char ch) {
|
||||
for (size_t i = 0; i < length; ++i) os_.put(ch);
|
||||
}
|
||||
|
||||
void AbslFormatFlush(StringifySink* sink, absl::string_view text) {
|
||||
sink->Append(text);
|
||||
}
|
||||
|
||||
} // namespace detect_specialization
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
484
TMessagesProj/jni/voip/webrtc/absl/log/internal/check_op.h
Normal file
484
TMessagesProj/jni/voip/webrtc/absl/log/internal/check_op.h
Normal file
|
|
@ -0,0 +1,484 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/check_op.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file declares helpers routines and macros used to implement `CHECK`
|
||||
// macros.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_CHECK_OP_H_
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OP_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstddef>
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/casts.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/log/internal/nullguard.h"
|
||||
#include "absl/log/internal/nullstream.h"
|
||||
#include "absl/log/internal/strip.h"
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
// `ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL` wraps string literals that
|
||||
// should be stripped when `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`.
|
||||
#ifdef ABSL_MIN_LOG_LEVEL
|
||||
#define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) \
|
||||
(::absl::LogSeverity::kFatal >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
|
||||
? (literal) \
|
||||
: "")
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(literal) (literal)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
// `NDEBUG` is defined, so `DCHECK_EQ(x, y)` and so on do nothing. However, we
|
||||
// still want the compiler to parse `x` and `y`, because we don't want to lose
|
||||
// potentially useful errors and warnings.
|
||||
#define ABSL_LOG_INTERNAL_DCHECK_NOP(x, y) \
|
||||
while (false && ((void)(x), (void)(y), 0)) \
|
||||
::absl::log_internal::NullStream().InternalStream()
|
||||
#endif
|
||||
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OP(name, op, val1, val1_text, val2, val2_text) \
|
||||
while (absl::Nullable<const char*> absl_log_internal_check_op_result \
|
||||
[[maybe_unused]] = \
|
||||
::absl::log_internal::name##Impl( \
|
||||
::absl::log_internal::GetReferenceableValue(val1), \
|
||||
::absl::log_internal::GetReferenceableValue(val2), \
|
||||
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
|
||||
val1_text " " #op " " val2_text))) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
|
||||
ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
|
||||
absl_log_internal_check_op_result)) \
|
||||
.InternalStream()
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
|
||||
val2_text) \
|
||||
while (absl::Nullable<const char*> absl_log_internal_qcheck_op_result = \
|
||||
::absl::log_internal::name##Impl( \
|
||||
::absl::log_internal::GetReferenceableValue(val1), \
|
||||
::absl::log_internal::GetReferenceableValue(val2), \
|
||||
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL( \
|
||||
val1_text " " #op " " val2_text))) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
|
||||
ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
|
||||
absl_log_internal_qcheck_op_result)) \
|
||||
.InternalStream()
|
||||
#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \
|
||||
s2_text) \
|
||||
while (absl::Nullable<const char*> absl_log_internal_check_strop_result = \
|
||||
::absl::log_internal::Check##func##expected##Impl( \
|
||||
(s1), (s2), \
|
||||
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \
|
||||
" " s2_text))) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
|
||||
ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
|
||||
absl_log_internal_check_strop_result)) \
|
||||
.InternalStream()
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \
|
||||
s2_text) \
|
||||
while (absl::Nullable<const char*> absl_log_internal_qcheck_strop_result = \
|
||||
::absl::log_internal::Check##func##expected##Impl( \
|
||||
(s1), (s2), \
|
||||
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(s1_text " " #op \
|
||||
" " s2_text))) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
|
||||
ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
|
||||
absl_log_internal_qcheck_strop_result)) \
|
||||
.InternalStream()
|
||||
|
||||
// This one is tricky:
|
||||
// * We must evaluate `val` exactly once, yet we need to do two things with it:
|
||||
// evaluate `.ok()` and (sometimes) `.ToString()`.
|
||||
// * `val` might be an `absl::Status` or some `absl::StatusOr<T>`.
|
||||
// * `val` might be e.g. `ATemporary().GetStatus()`, which may return a
|
||||
// reference to a member of `ATemporary` that is only valid until the end of
|
||||
// the full expression.
|
||||
// * We don't want this file to depend on `absl::Status` `#include`s or linkage,
|
||||
// nor do we want to move the definition to status and introduce a dependency
|
||||
// in the other direction. We can be assured that callers must already have a
|
||||
// `Status` and the necessary `#include`s and linkage.
|
||||
// * Callsites should be small and fast (at least when `val.ok()`): one branch,
|
||||
// minimal stack footprint.
|
||||
// * In particular, the string concat stuff should be out-of-line and emitted
|
||||
// in only one TU to save linker input size
|
||||
// * We want the `val.ok()` check inline so static analyzers and optimizers can
|
||||
// see it.
|
||||
// * As usual, no braces so we can stream into the expansion with `operator<<`.
|
||||
// * Also as usual, it must expand to a single (partial) statement with no
|
||||
// ambiguous-else problems.
|
||||
// * When stripped by `ABSL_MIN_LOG_LEVEL`, we must discard the `<expr> is OK`
|
||||
// string literal and abort without doing any streaming. We don't need to
|
||||
// strip the call to stringify the non-ok `Status` as long as we don't log it;
|
||||
// dropping the `Status`'s message text is out of scope.
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OK(val, val_text) \
|
||||
for (::std::pair<absl::Nonnull<const ::absl::Status*>, \
|
||||
absl::Nullable<const char*>> \
|
||||
absl_log_internal_check_ok_goo; \
|
||||
absl_log_internal_check_ok_goo.first = \
|
||||
::absl::log_internal::AsStatus(val), \
|
||||
absl_log_internal_check_ok_goo.second = \
|
||||
ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok()) \
|
||||
? nullptr \
|
||||
: ::absl::status_internal::MakeCheckFailString( \
|
||||
absl_log_internal_check_ok_goo.first, \
|
||||
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
|
||||
" is OK")), \
|
||||
!ABSL_PREDICT_TRUE(absl_log_internal_check_ok_goo.first->ok());) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_FATAL(STATELESS, true) \
|
||||
ABSL_LOG_INTERNAL_CHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
|
||||
absl_log_internal_check_ok_goo.second)) \
|
||||
.InternalStream()
|
||||
#define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \
|
||||
for (::std::pair<absl::Nonnull<const ::absl::Status*>, \
|
||||
absl::Nullable<const char*>> \
|
||||
absl_log_internal_qcheck_ok_goo; \
|
||||
absl_log_internal_qcheck_ok_goo.first = \
|
||||
::absl::log_internal::AsStatus(val), \
|
||||
absl_log_internal_qcheck_ok_goo.second = \
|
||||
ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok()) \
|
||||
? nullptr \
|
||||
: ::absl::status_internal::MakeCheckFailString( \
|
||||
absl_log_internal_qcheck_ok_goo.first, \
|
||||
ABSL_LOG_INTERNAL_STRIP_STRING_LITERAL(val_text \
|
||||
" is OK")), \
|
||||
!ABSL_PREDICT_TRUE(absl_log_internal_qcheck_ok_goo.first->ok());) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_QFATAL(STATELESS, true) \
|
||||
ABSL_LOG_INTERNAL_QCHECK(absl::implicit_cast<absl::Nonnull<const char*>>( \
|
||||
absl_log_internal_qcheck_ok_goo.second)) \
|
||||
.InternalStream()
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
class Status;
|
||||
template <typename T>
|
||||
class StatusOr;
|
||||
|
||||
namespace status_internal {
|
||||
ABSL_ATTRIBUTE_PURE_FUNCTION absl::Nonnull<const char*> MakeCheckFailString(
|
||||
absl::Nonnull<const absl::Status*> status,
|
||||
absl::Nonnull<const char*> prefix);
|
||||
} // namespace status_internal
|
||||
|
||||
namespace log_internal {
|
||||
|
||||
// Convert a Status or a StatusOr to its underlying status value.
|
||||
//
|
||||
// (This implementation does not require a dep on absl::Status to work.)
|
||||
inline absl::Nonnull<const absl::Status*> AsStatus(const absl::Status& s) {
|
||||
return &s;
|
||||
}
|
||||
template <typename T>
|
||||
absl::Nonnull<const absl::Status*> AsStatus(const absl::StatusOr<T>& s) {
|
||||
return &s.status();
|
||||
}
|
||||
|
||||
// A helper class for formatting `expr (V1 vs. V2)` in a `CHECK_XX` statement.
|
||||
// See `MakeCheckOpString` for sample usage.
|
||||
class CheckOpMessageBuilder final {
|
||||
public:
|
||||
// Inserts `exprtext` and ` (` to the stream.
|
||||
explicit CheckOpMessageBuilder(absl::Nonnull<const char*> exprtext);
|
||||
~CheckOpMessageBuilder() = default;
|
||||
// For inserting the first variable.
|
||||
std::ostream& ForVar1() { return stream_; }
|
||||
// For inserting the second variable (adds an intermediate ` vs. `).
|
||||
std::ostream& ForVar2();
|
||||
// Get the result (inserts the closing `)`).
|
||||
absl::Nonnull<const char*> NewString();
|
||||
|
||||
private:
|
||||
std::ostringstream stream_;
|
||||
};
|
||||
|
||||
// This formats a value for a failing `CHECK_XX` statement. Ordinarily, it uses
|
||||
// the definition for `operator<<`, with a few special cases below.
|
||||
template <typename T>
|
||||
inline void MakeCheckOpValueString(std::ostream& os, const T& v) {
|
||||
os << log_internal::NullGuard<T>::Guard(v);
|
||||
}
|
||||
|
||||
// Overloads for char types provide readable values for unprintable characters.
|
||||
void MakeCheckOpValueString(std::ostream& os, char v);
|
||||
void MakeCheckOpValueString(std::ostream& os, signed char v);
|
||||
void MakeCheckOpValueString(std::ostream& os, unsigned char v);
|
||||
void MakeCheckOpValueString(std::ostream& os, const void* p);
|
||||
|
||||
namespace detect_specialization {
|
||||
|
||||
// MakeCheckOpString is being specialized for every T and U pair that is being
|
||||
// passed to the CHECK_op macros. However, there is a lot of redundancy in these
|
||||
// specializations that creates unnecessary library and binary bloat.
|
||||
// The number of instantiations tends to be O(n^2) because we have two
|
||||
// independent inputs. This technique works by reducing `n`.
|
||||
//
|
||||
// Most user-defined types being passed to CHECK_op end up being printed as a
|
||||
// builtin type. For example, enums tend to be implicitly converted to its
|
||||
// underlying type when calling operator<<, and pointers are printed with the
|
||||
// `const void*` overload.
|
||||
// To reduce the number of instantiations we coerce these values before calling
|
||||
// MakeCheckOpString instead of inside it.
|
||||
//
|
||||
// To detect if this coercion is needed, we duplicate all the relevant
|
||||
// operator<< overloads as specified in the standard, just in a different
|
||||
// namespace. If the call to `stream << value` becomes ambiguous, it means that
|
||||
// one of these overloads is the one selected by overload resolution. We then
|
||||
// do overload resolution again just with our overload set to see which one gets
|
||||
// selected. That tells us which type to coerce to.
|
||||
// If the augmented call was not ambiguous, it means that none of these were
|
||||
// selected and we can't coerce the input.
|
||||
//
|
||||
// As a secondary step to reduce code duplication, we promote integral types to
|
||||
// their 64-bit variant. This does not change the printed value, but reduces the
|
||||
// number of instantiations even further. Promoting an integer is very cheap at
|
||||
// the call site.
|
||||
int64_t operator<<(std::ostream&, short value); // NOLINT
|
||||
int64_t operator<<(std::ostream&, unsigned short value); // NOLINT
|
||||
int64_t operator<<(std::ostream&, int value);
|
||||
int64_t operator<<(std::ostream&, unsigned int value);
|
||||
int64_t operator<<(std::ostream&, long value); // NOLINT
|
||||
uint64_t operator<<(std::ostream&, unsigned long value); // NOLINT
|
||||
int64_t operator<<(std::ostream&, long long value); // NOLINT
|
||||
uint64_t operator<<(std::ostream&, unsigned long long value); // NOLINT
|
||||
float operator<<(std::ostream&, float value);
|
||||
double operator<<(std::ostream&, double value);
|
||||
long double operator<<(std::ostream&, long double value);
|
||||
bool operator<<(std::ostream&, bool value);
|
||||
const void* operator<<(std::ostream&, const void* value);
|
||||
const void* operator<<(std::ostream&, std::nullptr_t);
|
||||
|
||||
// These `char` overloads are specified like this in the standard, so we have to
|
||||
// write them exactly the same to ensure the call is ambiguous.
|
||||
// If we wrote it in a different way (eg taking std::ostream instead of the
|
||||
// template) then one call might have a higher rank than the other and it would
|
||||
// not be ambiguous.
|
||||
template <typename Traits>
|
||||
char operator<<(std::basic_ostream<char, Traits>&, char);
|
||||
template <typename Traits>
|
||||
signed char operator<<(std::basic_ostream<char, Traits>&, signed char);
|
||||
template <typename Traits>
|
||||
unsigned char operator<<(std::basic_ostream<char, Traits>&, unsigned char);
|
||||
template <typename Traits>
|
||||
const char* operator<<(std::basic_ostream<char, Traits>&, const char*);
|
||||
template <typename Traits>
|
||||
const signed char* operator<<(std::basic_ostream<char, Traits>&,
|
||||
const signed char*);
|
||||
template <typename Traits>
|
||||
const unsigned char* operator<<(std::basic_ostream<char, Traits>&,
|
||||
const unsigned char*);
|
||||
|
||||
// This overload triggers when the call is not ambiguous.
|
||||
// It means that T is being printed with some overload not on this list.
|
||||
// We keep the value as `const T&`.
|
||||
template <typename T, typename = decltype(std::declval<std::ostream&>()
|
||||
<< std::declval<const T&>())>
|
||||
const T& Detect(int);
|
||||
|
||||
// This overload triggers when the call is ambiguous.
|
||||
// It means that T is either one from this list or printed as one from this
|
||||
// list. Eg an enum that decays to `int` for printing.
|
||||
// We ask the overload set to give us the type we want to convert it to.
|
||||
template <typename T>
|
||||
decltype(detect_specialization::operator<<(std::declval<std::ostream&>(),
|
||||
std::declval<const T&>()))
|
||||
Detect(char);
|
||||
|
||||
// A sink for AbslStringify which redirects everything to a std::ostream.
|
||||
class StringifySink {
|
||||
public:
|
||||
explicit StringifySink(std::ostream& os ABSL_ATTRIBUTE_LIFETIME_BOUND);
|
||||
|
||||
void Append(absl::string_view text);
|
||||
void Append(size_t length, char ch);
|
||||
friend void AbslFormatFlush(StringifySink* sink, absl::string_view text);
|
||||
|
||||
private:
|
||||
std::ostream& os_;
|
||||
};
|
||||
|
||||
// Wraps a type implementing AbslStringify, and implements operator<<.
|
||||
template <typename T>
|
||||
class StringifyToStreamWrapper {
|
||||
public:
|
||||
explicit StringifyToStreamWrapper(const T& v ABSL_ATTRIBUTE_LIFETIME_BOUND)
|
||||
: v_(v) {}
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,
|
||||
const StringifyToStreamWrapper& wrapper) {
|
||||
StringifySink sink(os);
|
||||
AbslStringify(sink, wrapper.v_);
|
||||
return os;
|
||||
}
|
||||
|
||||
private:
|
||||
const T& v_;
|
||||
};
|
||||
|
||||
// This overload triggers when T implements AbslStringify.
|
||||
// StringifyToStreamWrapper is used to allow MakeCheckOpString to use
|
||||
// operator<<.
|
||||
template <typename T>
|
||||
std::enable_if_t<HasAbslStringify<T>::value,
|
||||
StringifyToStreamWrapper<T>>
|
||||
Detect(...); // Ellipsis has lowest preference when int passed.
|
||||
} // namespace detect_specialization
|
||||
|
||||
template <typename T>
|
||||
using CheckOpStreamType = decltype(detect_specialization::Detect<T>(0));
|
||||
|
||||
// Build the error message string. Specify no inlining for code size.
|
||||
template <typename T1, typename T2>
|
||||
ABSL_ATTRIBUTE_RETURNS_NONNULL absl::Nonnull<const char*> MakeCheckOpString(
|
||||
T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) ABSL_ATTRIBUTE_NOINLINE;
|
||||
|
||||
template <typename T1, typename T2>
|
||||
absl::Nonnull<const char*> MakeCheckOpString(
|
||||
T1 v1, T2 v2, absl::Nonnull<const char*> exprtext) {
|
||||
CheckOpMessageBuilder comb(exprtext);
|
||||
MakeCheckOpValueString(comb.ForVar1(), v1);
|
||||
MakeCheckOpValueString(comb.ForVar2(), v2);
|
||||
return comb.NewString();
|
||||
}
|
||||
|
||||
// Add a few commonly used instantiations as extern to reduce size of objects
|
||||
// files.
|
||||
#define ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(x) \
|
||||
extern template absl::Nonnull<const char*> MakeCheckOpString( \
|
||||
x, x, absl::Nonnull<const char*>)
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(bool);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(int64_t);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(uint64_t);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(float);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(double);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(char);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(unsigned char);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const std::string&);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const absl::string_view&);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const char*);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const signed char*);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const unsigned char*);
|
||||
ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN(const void*);
|
||||
#undef ABSL_LOG_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING_EXTERN
|
||||
|
||||
// `ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT` skips formatting the Check_OP result
|
||||
// string iff `ABSL_MIN_LOG_LEVEL` exceeds `kFatal`, instead returning an empty
|
||||
// string.
|
||||
#ifdef ABSL_MIN_LOG_LEVEL
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
|
||||
((::absl::LogSeverity::kFatal >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL)) \
|
||||
? MakeCheckOpString<U1, U2>(v1, v2, exprtext) \
|
||||
: "")
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, v1, v2, exprtext) \
|
||||
MakeCheckOpString<U1, U2>(v1, v2, exprtext)
|
||||
#endif
|
||||
|
||||
// Helper functions for `ABSL_LOG_INTERNAL_CHECK_OP` macro family. The
|
||||
// `(int, int)` override works around the issue that the compiler will not
|
||||
// instantiate the template version of the function on values of unnamed enum
|
||||
// type.
|
||||
#define ABSL_LOG_INTERNAL_CHECK_OP_IMPL(name, op) \
|
||||
template <typename T1, typename T2> \
|
||||
inline constexpr absl::Nullable<const char*> name##Impl( \
|
||||
const T1& v1, const T2& v2, absl::Nonnull<const char*> exprtext) { \
|
||||
using U1 = CheckOpStreamType<T1>; \
|
||||
using U2 = CheckOpStreamType<T2>; \
|
||||
return ABSL_PREDICT_TRUE(v1 op v2) \
|
||||
? nullptr \
|
||||
: ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT(U1, U2, U1(v1), \
|
||||
U2(v2), exprtext); \
|
||||
} \
|
||||
inline constexpr absl::Nullable<const char*> name##Impl( \
|
||||
int v1, int v2, absl::Nonnull<const char*> exprtext) { \
|
||||
return name##Impl<int, int>(v1, v2, exprtext); \
|
||||
}
|
||||
|
||||
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_EQ, ==)
|
||||
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_NE, !=)
|
||||
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LE, <=)
|
||||
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_LT, <)
|
||||
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GE, >=)
|
||||
ABSL_LOG_INTERNAL_CHECK_OP_IMPL(Check_GT, >)
|
||||
#undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL_RESULT
|
||||
#undef ABSL_LOG_INTERNAL_CHECK_OP_IMPL
|
||||
|
||||
absl::Nullable<const char*> CheckstrcmptrueImpl(
|
||||
absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
|
||||
absl::Nonnull<const char*> exprtext);
|
||||
absl::Nullable<const char*> CheckstrcmpfalseImpl(
|
||||
absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
|
||||
absl::Nonnull<const char*> exprtext);
|
||||
absl::Nullable<const char*> CheckstrcasecmptrueImpl(
|
||||
absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
|
||||
absl::Nonnull<const char*> exprtext);
|
||||
absl::Nullable<const char*> CheckstrcasecmpfalseImpl(
|
||||
absl::Nullable<const char*> s1, absl::Nullable<const char*> s2,
|
||||
absl::Nonnull<const char*> exprtext);
|
||||
|
||||
// `CHECK_EQ` and friends want to pass their arguments by reference, however
|
||||
// this winds up exposing lots of cases where people have defined and
|
||||
// initialized static const data members but never declared them (i.e. in a .cc
|
||||
// file), meaning they are not referenceable. This function avoids that problem
|
||||
// for integers (the most common cases) by overloading for every primitive
|
||||
// integer type, even the ones we discourage, and returning them by value.
|
||||
// NOLINTBEGIN(runtime/int)
|
||||
// NOLINTBEGIN(google-runtime-int)
|
||||
template <typename T>
|
||||
inline constexpr const T& GetReferenceableValue(const T& t) {
|
||||
return t;
|
||||
}
|
||||
inline constexpr char GetReferenceableValue(char t) { return t; }
|
||||
inline constexpr unsigned char GetReferenceableValue(unsigned char t) {
|
||||
return t;
|
||||
}
|
||||
inline constexpr signed char GetReferenceableValue(signed char t) { return t; }
|
||||
inline constexpr short GetReferenceableValue(short t) { return t; }
|
||||
inline constexpr unsigned short GetReferenceableValue(unsigned short t) {
|
||||
return t;
|
||||
}
|
||||
inline constexpr int GetReferenceableValue(int t) { return t; }
|
||||
inline constexpr unsigned int GetReferenceableValue(unsigned int t) {
|
||||
return t;
|
||||
}
|
||||
inline constexpr long GetReferenceableValue(long t) { return t; }
|
||||
inline constexpr unsigned long GetReferenceableValue(unsigned long t) {
|
||||
return t;
|
||||
}
|
||||
inline constexpr long long GetReferenceableValue(long long t) { return t; }
|
||||
inline constexpr unsigned long long GetReferenceableValue(
|
||||
unsigned long long t) {
|
||||
return t;
|
||||
}
|
||||
// NOLINTEND(google-runtime-int)
|
||||
// NOLINTEND(runtime/int)
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_CHECK_OP_H_
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/conditions.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/cycleclock.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
|
||||
// The following code behaves like AtomicStatsCounter::LossyAdd() for
|
||||
// speed since it is fine to lose occasional updates.
|
||||
// Returns old value of *counter.
|
||||
uint32_t LossyIncrement(std::atomic<uint32_t>* counter) {
|
||||
const uint32_t value = counter->load(std::memory_order_relaxed);
|
||||
counter->store(value + 1, std::memory_order_relaxed);
|
||||
return value;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool LogEveryNState::ShouldLog(int n) {
|
||||
return n > 0 && (LossyIncrement(&counter_) % static_cast<uint32_t>(n)) == 0;
|
||||
}
|
||||
|
||||
bool LogFirstNState::ShouldLog(int n) {
|
||||
const uint32_t counter_value = counter_.load(std::memory_order_relaxed);
|
||||
if (static_cast<int64_t>(counter_value) < n) {
|
||||
counter_.store(counter_value + 1, std::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LogEveryPow2State::ShouldLog() {
|
||||
const uint32_t new_value = LossyIncrement(&counter_) + 1;
|
||||
return (new_value & (new_value - 1)) == 0;
|
||||
}
|
||||
|
||||
bool LogEveryNSecState::ShouldLog(double seconds) {
|
||||
using absl::base_internal::CycleClock;
|
||||
LossyIncrement(&counter_);
|
||||
const int64_t now_cycles = CycleClock::Now();
|
||||
int64_t next_cycles = next_log_time_cycles_.load(std::memory_order_relaxed);
|
||||
#if defined(__myriad2__)
|
||||
// myriad2 does not have 8-byte compare and exchange. Use a racy version that
|
||||
// is "good enough" but will over-log in the face of concurrent logging.
|
||||
if (now_cycles > next_cycles) {
|
||||
next_log_time_cycles_.store(now_cycles + seconds * CycleClock::Frequency(),
|
||||
std::memory_order_relaxed);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
#else
|
||||
do {
|
||||
if (now_cycles <= next_cycles) return false;
|
||||
} while (!next_log_time_cycles_.compare_exchange_weak(
|
||||
next_cycles, now_cycles + seconds * CycleClock::Frequency(),
|
||||
std::memory_order_relaxed, std::memory_order_relaxed));
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
239
TMessagesProj/jni/voip/webrtc/absl/log/internal/conditions.h
Normal file
239
TMessagesProj/jni/voip/webrtc/absl/log/internal/conditions.h
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/conditions.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file contains implementation of conditional log statements, like LOG_IF
|
||||
// including all the ABSL_LOG_INTERNAL_..._CONDITION_... macros and
|
||||
// various condition classes like LogEveryNState.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_CONDITIONS_H_
|
||||
#define ABSL_LOG_INTERNAL_CONDITIONS_H_
|
||||
|
||||
#if defined(_WIN32) || defined(__hexagon__)
|
||||
#include <cstdlib>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/voidify.h"
|
||||
|
||||
// `ABSL_LOG_INTERNAL_CONDITION` prefixes another macro that expands to a
|
||||
// temporary `LogMessage` instantiation followed by zero or more streamed
|
||||
// expressions. This definition is tricky to read correctly. It evaluates to
|
||||
// either
|
||||
//
|
||||
// (void)0;
|
||||
//
|
||||
// or
|
||||
//
|
||||
// ::absl::log_internal::Voidify() &&
|
||||
// ::absl::log_internal::LogMessage(...) << "the user's message";
|
||||
//
|
||||
// If the condition is evaluable at compile time, as is often the case, it
|
||||
// compiles away to just one side or the other.
|
||||
//
|
||||
// Although this is not used anywhere a statement (e.g. `if`) could not go,
|
||||
// the ternary expression does a better job avoiding spurious diagnostics
|
||||
// (dangling else, missing switch case) and preserving noreturn semantics (e.g.
|
||||
// on `LOG(FATAL)`) without requiring braces.
|
||||
//
|
||||
// The `switch` ensures that this expansion is the beginning of a statement (as
|
||||
// opposed to an expression) and prevents shenanigans like
|
||||
// `AFunction(LOG(INFO))` and `decltype(LOG(INFO))`. The apparently-redundant
|
||||
// `default` case makes the condition more amenable to Clang dataflow analysis.
|
||||
#define ABSL_LOG_INTERNAL_STATELESS_CONDITION(condition) \
|
||||
switch (0) \
|
||||
case 0: \
|
||||
default: \
|
||||
!(condition) ? (void)0 : ::absl::log_internal::Voidify()&&
|
||||
|
||||
// `ABSL_LOG_INTERNAL_STATEFUL_CONDITION` applies a condition like
|
||||
// `ABSL_LOG_INTERNAL_STATELESS_CONDITION` but adds to that a series of variable
|
||||
// declarations, including a local static object which stores the state needed
|
||||
// to implement the stateful macros like `LOG_EVERY_N`.
|
||||
//
|
||||
// `for`-loops are used to declare scoped variables without braces (to permit
|
||||
// streaming into the macro's expansion) and without the dangling-`else`
|
||||
// problems/diagnostics that come with `if`.
|
||||
//
|
||||
// Two more variables are declared in separate `for`-loops:
|
||||
//
|
||||
// * `COUNTER` implements a streamable token whose value when streamed is the
|
||||
// number of times execution has passed through the macro.
|
||||
// * A boolean flag is used to prevent any of the `for`-loops from ever actually
|
||||
// looping.
|
||||
#define ABSL_LOG_INTERNAL_STATEFUL_CONDITION(condition) \
|
||||
for (bool absl_log_internal_stateful_condition_do_log(condition); \
|
||||
absl_log_internal_stateful_condition_do_log; \
|
||||
absl_log_internal_stateful_condition_do_log = false) \
|
||||
ABSL_LOG_INTERNAL_STATEFUL_CONDITION_IMPL
|
||||
#define ABSL_LOG_INTERNAL_STATEFUL_CONDITION_IMPL(kind, ...) \
|
||||
for (static ::absl::log_internal::Log##kind##State \
|
||||
absl_log_internal_stateful_condition_state; \
|
||||
absl_log_internal_stateful_condition_do_log && \
|
||||
absl_log_internal_stateful_condition_state.ShouldLog(__VA_ARGS__); \
|
||||
absl_log_internal_stateful_condition_do_log = false) \
|
||||
for (const uint32_t COUNTER ABSL_ATTRIBUTE_UNUSED = \
|
||||
absl_log_internal_stateful_condition_state.counter(); \
|
||||
absl_log_internal_stateful_condition_do_log; \
|
||||
absl_log_internal_stateful_condition_do_log = false)
|
||||
|
||||
// `ABSL_LOG_INTERNAL_CONDITION_*` serve to combine any conditions from the
|
||||
// macro (e.g. `LOG_IF` or `VLOG`) with inherent conditions (e.g.
|
||||
// `ABSL_MIN_LOG_LEVEL`) into a single boolean expression. We could chain
|
||||
// ternary operators instead, however some versions of Clang sometimes issue
|
||||
// spurious diagnostics after such expressions due to a control flow analysis
|
||||
// bug.
|
||||
#ifdef ABSL_MIN_LOG_LEVEL
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION( \
|
||||
(condition) && ::absl::LogSeverity::kInfo >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_WARNING(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION( \
|
||||
(condition) && ::absl::LogSeverity::kWarning >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION( \
|
||||
(condition) && ::absl::LogSeverity::kError >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL))
|
||||
// NOTE: Use ternary operators instead of short-circuiting to mitigate
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=51928.
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION( \
|
||||
((condition) \
|
||||
? (::absl::LogSeverity::kFatal >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
|
||||
? true \
|
||||
: (::absl::log_internal::AbortQuietly(), false)) \
|
||||
: false))
|
||||
// NOTE: Use ternary operators instead of short-circuiting to mitigate
|
||||
// https://bugs.llvm.org/show_bug.cgi?id=51928.
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION( \
|
||||
((condition) \
|
||||
? (::absl::LogSeverity::kFatal >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) \
|
||||
? true \
|
||||
: (::absl::log_internal::ExitQuietly(), false)) \
|
||||
: false))
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION( \
|
||||
(ABSL_ASSUME(absl::kLogDebugFatal == absl::LogSeverity::kError || \
|
||||
absl::kLogDebugFatal == absl::LogSeverity::kFatal), \
|
||||
(condition) && \
|
||||
(::absl::kLogDebugFatal >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) || \
|
||||
(::absl::kLogDebugFatal == ::absl::LogSeverity::kFatal && \
|
||||
(::absl::log_internal::AbortQuietly(), false)))))
|
||||
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity) \
|
||||
for (int absl_log_internal_severity_loop = 1; \
|
||||
absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
|
||||
for (const absl::LogSeverity absl_log_internal_severity = \
|
||||
::absl::NormalizeLogSeverity(severity); \
|
||||
absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(( \
|
||||
(condition) && \
|
||||
(absl_log_internal_severity >= \
|
||||
static_cast<::absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) || \
|
||||
(absl_log_internal_severity == ::absl::LogSeverity::kFatal && \
|
||||
(::absl::log_internal::AbortQuietly(), false)))))
|
||||
#else // ndef ABSL_MIN_LOG_LEVEL
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_INFO(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_WARNING(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_ERROR(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_FATAL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_QFATAL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_DFATAL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_LEVEL(severity) \
|
||||
for (int absl_log_internal_severity_loop = 1; \
|
||||
absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
|
||||
for (const absl::LogSeverity absl_log_internal_severity = \
|
||||
::absl::NormalizeLogSeverity(severity); \
|
||||
absl_log_internal_severity_loop; absl_log_internal_severity_loop = 0) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL
|
||||
#define ABSL_LOG_INTERNAL_CONDITION_LEVEL_IMPL(type, condition) \
|
||||
ABSL_LOG_INTERNAL_##type##_CONDITION(condition)
|
||||
#endif // ndef ABSL_MIN_LOG_LEVEL
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// Stateful condition class name should be "Log" + name + "State".
|
||||
class LogEveryNState final {
|
||||
public:
|
||||
bool ShouldLog(int n);
|
||||
uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
|
||||
|
||||
private:
|
||||
std::atomic<uint32_t> counter_{0};
|
||||
};
|
||||
|
||||
class LogFirstNState final {
|
||||
public:
|
||||
bool ShouldLog(int n);
|
||||
uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
|
||||
|
||||
private:
|
||||
std::atomic<uint32_t> counter_{0};
|
||||
};
|
||||
|
||||
class LogEveryPow2State final {
|
||||
public:
|
||||
bool ShouldLog();
|
||||
uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
|
||||
|
||||
private:
|
||||
std::atomic<uint32_t> counter_{0};
|
||||
};
|
||||
|
||||
class LogEveryNSecState final {
|
||||
public:
|
||||
bool ShouldLog(double seconds);
|
||||
uint32_t counter() { return counter_.load(std::memory_order_relaxed); }
|
||||
|
||||
private:
|
||||
std::atomic<uint32_t> counter_{0};
|
||||
// Cycle count according to CycleClock that we should next log at.
|
||||
std::atomic<int64_t> next_log_time_cycles_{0};
|
||||
};
|
||||
|
||||
// Helper routines to abort the application quietly
|
||||
|
||||
[[noreturn]] inline void AbortQuietly() { abort(); }
|
||||
[[noreturn]] inline void ExitQuietly() { _exit(1); }
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_CONDITIONS_H_
|
||||
45
TMessagesProj/jni/voip/webrtc/absl/log/internal/config.h
Normal file
45
TMessagesProj/jni/voip/webrtc/absl/log/internal/config.h
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/config.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_CONFIG_H_
|
||||
#define ABSL_LOG_INTERNAL_CONFIG_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cstdint>
|
||||
#else
|
||||
#include <sys/types.h>
|
||||
#endif
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
#ifdef _WIN32
|
||||
using Tid = uint32_t;
|
||||
#else
|
||||
using Tid = pid_t;
|
||||
#endif
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_CONFIG_H_
|
||||
59
TMessagesProj/jni/voip/webrtc/absl/log/internal/flags.h
Normal file
59
TMessagesProj/jni/voip/webrtc/absl/log/internal/flags.h
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/log_flags.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares set of flags which can be used to configure Abseil
|
||||
// Logging library behaviour at runtime.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_FLAGS_H_
|
||||
#define ABSL_LOG_INTERNAL_FLAGS_H_
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/flags/declare.h"
|
||||
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// These flags should not be used in C++ code to access logging library
|
||||
// configuration knobs. Use interfaces defined in absl/log/globals.h
|
||||
// instead. It is still ok to use these flags on a command line.
|
||||
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
// Log messages at this severity or above are sent to stderr in *addition* to
|
||||
// `LogSink`s. Defaults to `ERROR`. See log_severity.h for numeric values of
|
||||
// severity levels.
|
||||
ABSL_DECLARE_FLAG(int, stderrthreshold);
|
||||
|
||||
// Log messages at this severity or above are logged; others are discarded.
|
||||
// Defaults to `INFO`, i.e. log all severities. See log_severity.h for numeric
|
||||
// values of severity levels.
|
||||
ABSL_DECLARE_FLAG(int, minloglevel);
|
||||
|
||||
// If specified in the form file:linenum, any messages logged from a matching
|
||||
// location will also include a backtrace.
|
||||
ABSL_DECLARE_FLAG(std::string, log_backtrace_at);
|
||||
|
||||
// If true, the log prefix (severity, date, time, PID, etc.) is prepended to
|
||||
// each message logged. Defaults to true.
|
||||
ABSL_DECLARE_FLAG(bool, log_prefix);
|
||||
|
||||
// Global log verbosity level. Default is 0.
|
||||
ABSL_DECLARE_FLAG(int, v);
|
||||
|
||||
// Per-module log verbosity level. By default is empty and is unused.
|
||||
ABSL_DECLARE_FLAG(std::string, vmodule);
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_FLAGS_H_
|
||||
73
TMessagesProj/jni/voip/webrtc/absl/log/internal/fnmatch.cc
Normal file
73
TMessagesProj/jni/voip/webrtc/absl/log/internal/fnmatch.cc
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
// Copyright 2023 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/fnmatch.h"
|
||||
|
||||
#include <cstddef>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
bool FNMatch(absl::string_view pattern, absl::string_view str) {
|
||||
bool in_wildcard_match = false;
|
||||
while (true) {
|
||||
if (pattern.empty()) {
|
||||
// `pattern` is exhausted; succeed if all of `str` was consumed matching
|
||||
// it.
|
||||
return in_wildcard_match || str.empty();
|
||||
}
|
||||
if (str.empty()) {
|
||||
// `str` is exhausted; succeed if `pattern` is empty or all '*'s.
|
||||
return pattern.find_first_not_of('*') == pattern.npos;
|
||||
}
|
||||
switch (pattern.front()) {
|
||||
case '*':
|
||||
pattern.remove_prefix(1);
|
||||
in_wildcard_match = true;
|
||||
break;
|
||||
case '?':
|
||||
pattern.remove_prefix(1);
|
||||
str.remove_prefix(1);
|
||||
break;
|
||||
default:
|
||||
if (in_wildcard_match) {
|
||||
absl::string_view fixed_portion = pattern;
|
||||
const size_t end = fixed_portion.find_first_of("*?");
|
||||
if (end != fixed_portion.npos) {
|
||||
fixed_portion = fixed_portion.substr(0, end);
|
||||
}
|
||||
const size_t match = str.find(fixed_portion);
|
||||
if (match == str.npos) {
|
||||
return false;
|
||||
}
|
||||
pattern.remove_prefix(fixed_portion.size());
|
||||
str.remove_prefix(match + fixed_portion.size());
|
||||
in_wildcard_match = false;
|
||||
} else {
|
||||
if (pattern.front() != str.front()) {
|
||||
return false;
|
||||
}
|
||||
pattern.remove_prefix(1);
|
||||
str.remove_prefix(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
35
TMessagesProj/jni/voip/webrtc/absl/log/internal/fnmatch.h
Normal file
35
TMessagesProj/jni/voip/webrtc/absl/log/internal/fnmatch.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2023 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_FNMATCH_H_
|
||||
#define ABSL_LOG_INTERNAL_FNMATCH_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
// Like POSIX `fnmatch`, but:
|
||||
// * accepts `string_view`
|
||||
// * does not allocate any dynamic memory
|
||||
// * only supports * and ? wildcards and not bracket expressions [...]
|
||||
// * wildcards may match /
|
||||
// * no backslash-escaping
|
||||
bool FNMatch(absl::string_view pattern, absl::string_view str);
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_FNMATCH_H_
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
// Copyright 2023 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/fnmatch.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
void BM_FNMatch(benchmark::State& state) {
|
||||
while (state.KeepRunning()) {
|
||||
bool ret =
|
||||
absl::log_internal::FNMatch("*?*asdf*?*we???asdf**asdf*we",
|
||||
"QWERFASVWERASDFWEDFASDasdfQWERGFWASDERREWF"
|
||||
"weHOOasdf@#$%TW#ZSERasdfQW#REGTZSERERwe");
|
||||
benchmark::DoNotOptimize(ret);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_FNMatch);
|
||||
} // namespace
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
// Copyright 2023 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/fnmatch.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
namespace {
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::IsTrue;
|
||||
|
||||
TEST(FNMatchTest, Works) {
|
||||
using absl::log_internal::FNMatch;
|
||||
EXPECT_THAT(FNMatch("foo", "foo"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("foo", "bar"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("foo", "fo"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("foo", "foo2"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("bar/foo.ext", "bar/foo.ext"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("*ba*r/fo*o.ext*", "bar/foo.ext"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("bar/foo.ext", "bar/baz.ext"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("bar/foo.ext", "bar/foo"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("bar/foo.ext", "bar/foo.ext.zip"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("ba?/*.ext", "bar/foo.ext"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("ba?/*.ext", "baZ/FOO.ext"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("ba?/*.ext", "barr/foo.ext"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("ba?/*.ext", "bar/foo.ext2"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("ba?/*", "bar/foo.ext2"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("ba?/*", "bar/"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("ba?/?", "bar/"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("ba?/*", "bar"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("?x", "zx"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("*b", "aab"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("a*b", "aXb"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("", ""), IsTrue());
|
||||
EXPECT_THAT(FNMatch("", "a"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("ab*", "ab"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("ab**", "ab"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("ab*?", "ab"), IsFalse());
|
||||
EXPECT_THAT(FNMatch("*", "bbb"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("*", ""), IsTrue());
|
||||
EXPECT_THAT(FNMatch("?", ""), IsFalse());
|
||||
EXPECT_THAT(FNMatch("***", "**p"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("**", "*"), IsTrue());
|
||||
EXPECT_THAT(FNMatch("*?", "*"), IsTrue());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
145
TMessagesProj/jni/voip/webrtc/absl/log/internal/globals.cc
Normal file
145
TMessagesProj/jni/voip/webrtc/absl/log/internal/globals.cc
Normal file
|
|
@ -0,0 +1,145 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/globals.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdio>
|
||||
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
#include <emscripten/console.h>
|
||||
#endif
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
namespace {
|
||||
// Keeps track of whether Logging initialization is finalized.
|
||||
// Log messages generated before that will go to stderr.
|
||||
ABSL_CONST_INIT std::atomic<bool> logging_initialized(false);
|
||||
|
||||
// The TimeZone used for logging. This may only be set once.
|
||||
ABSL_CONST_INIT std::atomic<absl::TimeZone*> timezone_ptr{nullptr};
|
||||
|
||||
// If true, the logging library will symbolize stack in fatal messages
|
||||
ABSL_CONST_INIT std::atomic<bool> symbolize_stack_trace(true);
|
||||
|
||||
// Specifies maximum number of stack frames to report in fatal messages.
|
||||
ABSL_CONST_INIT std::atomic<int> max_frames_in_stack_trace(64);
|
||||
|
||||
ABSL_CONST_INIT std::atomic<bool> exit_on_dfatal(true);
|
||||
ABSL_CONST_INIT std::atomic<bool> suppress_sigabort_trace(false);
|
||||
} // namespace
|
||||
|
||||
bool IsInitialized() {
|
||||
return logging_initialized.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void SetInitialized() {
|
||||
logging_initialized.store(true, std::memory_order_release);
|
||||
}
|
||||
|
||||
void WriteToStderr(absl::string_view message, absl::LogSeverity severity) {
|
||||
if (message.empty()) return;
|
||||
#if defined(__EMSCRIPTEN__)
|
||||
// In WebAssembly, bypass filesystem emulation via fwrite.
|
||||
// Skip a trailing newline character as emscripten_errn adds one itself.
|
||||
const auto message_minus_newline = absl::StripSuffix(message, "\n");
|
||||
// emscripten_errn was introduced in 3.1.41 but broken in standalone mode
|
||||
// until 3.1.43.
|
||||
#if ABSL_INTERNAL_EMSCRIPTEN_VERSION >= 3001043
|
||||
emscripten_errn(message_minus_newline.data(), message_minus_newline.size());
|
||||
#else
|
||||
std::string null_terminated_message(message_minus_newline);
|
||||
_emscripten_err(null_terminated_message.c_str());
|
||||
#endif
|
||||
#else
|
||||
// Avoid using std::cerr from this module since we may get called during
|
||||
// exit code, and cerr may be partially or fully destroyed by then.
|
||||
std::fwrite(message.data(), message.size(), 1, stderr);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN64) || defined(_WIN32) || defined(_WIN16)
|
||||
// C99 requires stderr to not be fully-buffered by default (7.19.3.7), but
|
||||
// MS CRT buffers it anyway, so we must `fflush` to ensure the string hits
|
||||
// the console/file before the program dies (and takes the libc buffers
|
||||
// with it).
|
||||
// https://docs.microsoft.com/en-us/cpp/c-runtime-library/stream-i-o
|
||||
if (severity >= absl::LogSeverity::kWarning) {
|
||||
std::fflush(stderr);
|
||||
}
|
||||
#else
|
||||
// Avoid unused parameter warning in this branch.
|
||||
(void)severity;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SetTimeZone(absl::TimeZone tz) {
|
||||
absl::TimeZone* expected = nullptr;
|
||||
absl::TimeZone* new_tz = new absl::TimeZone(tz);
|
||||
// timezone_ptr can only be set once, otherwise new_tz is leaked.
|
||||
if (!timezone_ptr.compare_exchange_strong(expected, new_tz,
|
||||
std::memory_order_release,
|
||||
std::memory_order_relaxed)) {
|
||||
ABSL_RAW_LOG(FATAL,
|
||||
"absl::log_internal::SetTimeZone() has already been called");
|
||||
}
|
||||
}
|
||||
|
||||
const absl::TimeZone* TimeZone() {
|
||||
return timezone_ptr.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
bool ShouldSymbolizeLogStackTrace() {
|
||||
return symbolize_stack_trace.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void EnableSymbolizeLogStackTrace(bool on_off) {
|
||||
symbolize_stack_trace.store(on_off, std::memory_order_release);
|
||||
}
|
||||
|
||||
int MaxFramesInLogStackTrace() {
|
||||
return max_frames_in_stack_trace.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
void SetMaxFramesInLogStackTrace(int max_num_frames) {
|
||||
max_frames_in_stack_trace.store(max_num_frames, std::memory_order_release);
|
||||
}
|
||||
|
||||
bool ExitOnDFatal() { return exit_on_dfatal.load(std::memory_order_acquire); }
|
||||
|
||||
void SetExitOnDFatal(bool on_off) {
|
||||
exit_on_dfatal.store(on_off, std::memory_order_release);
|
||||
}
|
||||
|
||||
bool SuppressSigabortTrace() {
|
||||
return suppress_sigabort_trace.load(std::memory_order_acquire);
|
||||
}
|
||||
|
||||
bool SetSuppressSigabortTrace(bool on_off) {
|
||||
return suppress_sigabort_trace.exchange(on_off);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
101
TMessagesProj/jni/voip/webrtc/absl/log/internal/globals.h
Normal file
101
TMessagesProj/jni/voip/webrtc/absl/log/internal/globals.h
Normal file
|
|
@ -0,0 +1,101 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/globals.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header file contains various global objects and static helper routines
|
||||
// use in logging implementation.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_GLOBALS_H_
|
||||
#define ABSL_LOG_INTERNAL_GLOBALS_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// IsInitialized returns true if the logging library is initialized.
|
||||
// This function is async-signal-safe
|
||||
bool IsInitialized();
|
||||
|
||||
// SetLoggingInitialized is called once after logging initialization is done.
|
||||
void SetInitialized();
|
||||
|
||||
// Unconditionally write a `message` to stderr. If `severity` exceeds kInfo
|
||||
// we also flush the stderr stream.
|
||||
void WriteToStderr(absl::string_view message, absl::LogSeverity severity);
|
||||
|
||||
// Set the TimeZone used for human-friendly times (for example, the log message
|
||||
// prefix) printed by the logging library. This may only be called once.
|
||||
void SetTimeZone(absl::TimeZone tz);
|
||||
|
||||
// Returns the TimeZone used for human-friendly times (for example, the log
|
||||
// message prefix) printed by the logging library Returns nullptr prior to
|
||||
// initialization.
|
||||
const absl::TimeZone* TimeZone();
|
||||
|
||||
// Returns true if stack traces emitted by the logging library should be
|
||||
// symbolized. This function is async-signal-safe.
|
||||
bool ShouldSymbolizeLogStackTrace();
|
||||
|
||||
// Enables or disables symbolization of stack traces emitted by the
|
||||
// logging library. This function is async-signal-safe.
|
||||
void EnableSymbolizeLogStackTrace(bool on_off);
|
||||
|
||||
// Returns the maximum number of frames that appear in stack traces
|
||||
// emitted by the logging library. This function is async-signal-safe.
|
||||
int MaxFramesInLogStackTrace();
|
||||
|
||||
// Sets the maximum number of frames that appear in stack traces emitted by
|
||||
// the logging library. This function is async-signal-safe.
|
||||
void SetMaxFramesInLogStackTrace(int max_num_frames);
|
||||
|
||||
// Determines whether we exit the program for a LOG(DFATAL) message in
|
||||
// debug mode. It does this by skipping the call to Fail/FailQuietly.
|
||||
// This is intended for testing only.
|
||||
//
|
||||
// This can have some effects on LOG(FATAL) as well. Failure messages
|
||||
// are always allocated (rather than sharing a buffer), the crash
|
||||
// reason is not recorded, the "gwq" status message is not updated,
|
||||
// and the stack trace is not recorded. The LOG(FATAL) *will* still
|
||||
// exit the program. Since this function is used only in testing,
|
||||
// these differences are acceptable.
|
||||
//
|
||||
// Additionally, LOG(LEVEL(FATAL)) is indistinguishable from LOG(DFATAL) and
|
||||
// will not terminate the program if SetExitOnDFatal(false) has been called.
|
||||
bool ExitOnDFatal();
|
||||
|
||||
// SetExitOnDFatal() sets the ExitOnDFatal() status
|
||||
void SetExitOnDFatal(bool on_off);
|
||||
|
||||
// Determines if the logging library should suppress logging of stacktraces in
|
||||
// the `SIGABRT` handler, typically because we just logged a stacktrace as part
|
||||
// of `LOG(FATAL)` and are about to send ourselves a `SIGABRT` to end the
|
||||
// program.
|
||||
bool SuppressSigabortTrace();
|
||||
|
||||
// Sets the SuppressSigabortTrace() status and returns the previous state.
|
||||
bool SetSuppressSigabortTrace(bool on_off);
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_GLOBALS_H_
|
||||
205
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_format.cc
Normal file
205
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_format.cc
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/log_format.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include <winsock2.h> // For timeval
|
||||
#else
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/log/internal/append_truncated.h"
|
||||
#include "absl/log/internal/config.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/civil_time.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
|
||||
// This templated function avoids compiler warnings about tautological
|
||||
// comparisons when log_internal::Tid is unsigned. It can be replaced with a
|
||||
// constexpr if once the minimum C++ version Abseil supports is C++17.
|
||||
template <typename T>
|
||||
inline std::enable_if_t<!std::is_signed<T>::value>
|
||||
PutLeadingWhitespace(T tid, char*& p) {
|
||||
if (tid < 10) *p++ = ' ';
|
||||
if (tid < 100) *p++ = ' ';
|
||||
if (tid < 1000) *p++ = ' ';
|
||||
if (tid < 10000) *p++ = ' ';
|
||||
if (tid < 100000) *p++ = ' ';
|
||||
if (tid < 1000000) *p++ = ' ';
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::enable_if_t<std::is_signed<T>::value>
|
||||
PutLeadingWhitespace(T tid, char*& p) {
|
||||
if (tid >= 0 && tid < 10) *p++ = ' ';
|
||||
if (tid > -10 && tid < 100) *p++ = ' ';
|
||||
if (tid > -100 && tid < 1000) *p++ = ' ';
|
||||
if (tid > -1000 && tid < 10000) *p++ = ' ';
|
||||
if (tid > -10000 && tid < 100000) *p++ = ' ';
|
||||
if (tid > -100000 && tid < 1000000) *p++ = ' ';
|
||||
}
|
||||
|
||||
// The fields before the filename are all fixed-width except for the thread ID,
|
||||
// which is of bounded width.
|
||||
size_t FormatBoundedFields(absl::LogSeverity severity, absl::Time timestamp,
|
||||
log_internal::Tid tid, absl::Span<char>& buf) {
|
||||
constexpr size_t kBoundedFieldsMaxLen =
|
||||
sizeof("SMMDD HH:MM:SS.NNNNNN ") +
|
||||
(1 + std::numeric_limits<log_internal::Tid>::digits10 + 1) - sizeof("");
|
||||
if (ABSL_PREDICT_FALSE(buf.size() < kBoundedFieldsMaxLen)) {
|
||||
// We don't bother trying to truncate these fields if the buffer is too
|
||||
// short (or almost too short) because it would require doing a lot more
|
||||
// length checking (slow) and it should never happen. A 15kB buffer should
|
||||
// be enough for anyone. Instead we mark `buf` full without writing
|
||||
// anything.
|
||||
buf.remove_suffix(buf.size());
|
||||
return 0;
|
||||
}
|
||||
|
||||
// We can't call absl::LocalTime(), localtime_r(), or anything else here that
|
||||
// isn't async-signal-safe. We can only use the time zone if it has already
|
||||
// been loaded.
|
||||
const absl::TimeZone* tz = absl::log_internal::TimeZone();
|
||||
if (ABSL_PREDICT_FALSE(tz == nullptr)) {
|
||||
// If a time zone hasn't been set yet because we are logging before the
|
||||
// logging library has been initialized, we fallback to a simpler, slower
|
||||
// method. Just report the raw Unix time in seconds. We cram this into the
|
||||
// normal time format for the benefit of parsers.
|
||||
auto tv = absl::ToTimeval(timestamp);
|
||||
int snprintf_result = absl::SNPrintF(
|
||||
buf.data(), buf.size(), "%c0000 00:00:%02d.%06d %7d ",
|
||||
absl::LogSeverityName(severity)[0], static_cast<int>(tv.tv_sec),
|
||||
static_cast<int>(tv.tv_usec), static_cast<int>(tid));
|
||||
if (snprintf_result >= 0) {
|
||||
buf.remove_prefix(static_cast<size_t>(snprintf_result));
|
||||
return static_cast<size_t>(snprintf_result);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
char* p = buf.data();
|
||||
*p++ = absl::LogSeverityName(severity)[0];
|
||||
const absl::TimeZone::CivilInfo ci = tz->At(timestamp);
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(ci.cs.month()), p);
|
||||
p += 2;
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(ci.cs.day()), p);
|
||||
p += 2;
|
||||
*p++ = ' ';
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(ci.cs.hour()), p);
|
||||
p += 2;
|
||||
*p++ = ':';
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(ci.cs.minute()),
|
||||
p);
|
||||
p += 2;
|
||||
*p++ = ':';
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(ci.cs.second()),
|
||||
p);
|
||||
p += 2;
|
||||
*p++ = '.';
|
||||
const int64_t usecs = absl::ToInt64Microseconds(ci.subsecond);
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(usecs / 10000), p);
|
||||
p += 2;
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(usecs / 100 % 100),
|
||||
p);
|
||||
p += 2;
|
||||
absl::numbers_internal::PutTwoDigits(static_cast<uint32_t>(usecs % 100), p);
|
||||
p += 2;
|
||||
*p++ = ' ';
|
||||
PutLeadingWhitespace(tid, p);
|
||||
p = absl::numbers_internal::FastIntToBuffer(tid, p);
|
||||
*p++ = ' ';
|
||||
const size_t bytes_formatted = static_cast<size_t>(p - buf.data());
|
||||
buf.remove_prefix(bytes_formatted);
|
||||
return bytes_formatted;
|
||||
}
|
||||
|
||||
size_t FormatLineNumber(int line, absl::Span<char>& buf) {
|
||||
constexpr size_t kLineFieldMaxLen =
|
||||
sizeof(":] ") + (1 + std::numeric_limits<int>::digits10 + 1) - sizeof("");
|
||||
if (ABSL_PREDICT_FALSE(buf.size() < kLineFieldMaxLen)) {
|
||||
// As above, we don't bother trying to truncate this if the buffer is too
|
||||
// short and it should never happen.
|
||||
buf.remove_suffix(buf.size());
|
||||
return 0;
|
||||
}
|
||||
char* p = buf.data();
|
||||
*p++ = ':';
|
||||
p = absl::numbers_internal::FastIntToBuffer(line, p);
|
||||
*p++ = ']';
|
||||
*p++ = ' ';
|
||||
const size_t bytes_formatted = static_cast<size_t>(p - buf.data());
|
||||
buf.remove_prefix(bytes_formatted);
|
||||
return bytes_formatted;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
std::string FormatLogMessage(absl::LogSeverity severity,
|
||||
absl::CivilSecond civil_second,
|
||||
absl::Duration subsecond, log_internal::Tid tid,
|
||||
absl::string_view basename, int line,
|
||||
PrefixFormat format, absl::string_view message) {
|
||||
return absl::StrFormat(
|
||||
"%c%02d%02d %02d:%02d:%02d.%06d %7d %s:%d] %s%s",
|
||||
absl::LogSeverityName(severity)[0], civil_second.month(),
|
||||
civil_second.day(), civil_second.hour(), civil_second.minute(),
|
||||
civil_second.second(), absl::ToInt64Microseconds(subsecond), tid,
|
||||
basename, line, format == PrefixFormat::kRaw ? "RAW: " : "", message);
|
||||
}
|
||||
|
||||
// This method is fairly hot, and the library always passes a huge `buf`, so we
|
||||
// save some bounds-checking cycles by not trying to do precise truncation.
|
||||
// Truncating at a field boundary is probably a better UX anyway.
|
||||
//
|
||||
// The prefix is written in three parts, each of which does a single
|
||||
// bounds-check and truncation:
|
||||
// 1. severity, timestamp, and thread ID
|
||||
// 2. filename
|
||||
// 3. line number and bracket
|
||||
size_t FormatLogPrefix(absl::LogSeverity severity, absl::Time timestamp,
|
||||
log_internal::Tid tid, absl::string_view basename,
|
||||
int line, PrefixFormat format, absl::Span<char>& buf) {
|
||||
auto prefix_size = FormatBoundedFields(severity, timestamp, tid, buf);
|
||||
prefix_size += log_internal::AppendTruncated(basename, buf);
|
||||
prefix_size += FormatLineNumber(line, buf);
|
||||
if (format == PrefixFormat::kRaw)
|
||||
prefix_size += log_internal::AppendTruncated("RAW: ", buf);
|
||||
return prefix_size;
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
78
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_format.h
Normal file
78
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_format.h
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/log_format.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file declares routines implementing formatting of log message and log
|
||||
// prefix.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_LOG_FORMAT_H_
|
||||
#define ABSL_LOG_INTERNAL_LOG_FORMAT_H_
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/civil_time.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
enum class PrefixFormat {
|
||||
kNotRaw,
|
||||
kRaw,
|
||||
};
|
||||
|
||||
// Formats log message based on provided data.
|
||||
std::string FormatLogMessage(absl::LogSeverity severity,
|
||||
absl::CivilSecond civil_second,
|
||||
absl::Duration subsecond, log_internal::Tid tid,
|
||||
absl::string_view basename, int line,
|
||||
PrefixFormat format, absl::string_view message);
|
||||
|
||||
// Formats various entry metadata into a text string meant for use as a
|
||||
// prefix on a log message string. Writes into `buf`, advances `buf` to point
|
||||
// at the remainder of the buffer (i.e. past any written bytes), and returns the
|
||||
// number of bytes written.
|
||||
//
|
||||
// In addition to calling `buf->remove_prefix()` (or the equivalent), this
|
||||
// function may also do `buf->remove_suffix(buf->size())` in cases where no more
|
||||
// bytes (i.e. no message data) should be written into the buffer. For example,
|
||||
// if the prefix ought to be:
|
||||
// I0926 09:00:00.000000 1234567 foo.cc:123]
|
||||
// `buf` is too small, the function might fill the whole buffer:
|
||||
// I0926 09:00:00.000000 1234
|
||||
// (note the apparrently incorrect thread ID), or it might write less:
|
||||
// I0926 09:00:00.000000
|
||||
// In this case, it might also empty `buf` prior to returning to prevent
|
||||
// message data from being written into the space where a reader would expect to
|
||||
// see a thread ID.
|
||||
size_t FormatLogPrefix(absl::LogSeverity severity, absl::Time timestamp,
|
||||
log_internal::Tid tid, absl::string_view basename,
|
||||
int line, PrefixFormat format, absl::Span<char>& buf);
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_LOG_FORMAT_H_
|
||||
282
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_impl.h
Normal file
282
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_impl.h
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
// Copyright 2022 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_LOG_IMPL_H_
|
||||
#define ABSL_LOG_INTERNAL_LOG_IMPL_H_
|
||||
|
||||
#include "absl/log/absl_vlog_is_on.h"
|
||||
#include "absl/log/internal/conditions.h"
|
||||
#include "absl/log/internal/log_message.h"
|
||||
#include "absl/log/internal/strip.h"
|
||||
|
||||
// ABSL_LOG()
|
||||
#define ABSL_LOG_INTERNAL_LOG_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
// ABSL_PLOG()
|
||||
#define ABSL_LOG_INTERNAL_PLOG_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
// ABSL_DLOG()
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, true) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
#endif
|
||||
|
||||
// The `switch` ensures that this expansion is the beginning of a statement (as
|
||||
// opposed to an expression). The use of both `case 0` and `default` is to
|
||||
// suppress a compiler warning.
|
||||
#define ABSL_LOG_INTERNAL_VLOG_IMPL(verbose_level) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_IMPL( \
|
||||
_INFO, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
.WithVerbosity(absl_logging_internal_verbose_level)
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_IMPL( \
|
||||
_INFO, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
.WithVerbosity(absl_logging_internal_verbose_level)
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_DVLOG_IMPL(verbose_level) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_IMPL( \
|
||||
_INFO, false && ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
.WithVerbosity(absl_logging_internal_verbose_level)
|
||||
#endif
|
||||
|
||||
#define ABSL_LOG_INTERNAL_LOG_IF_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
#define ABSL_LOG_INTERNAL_PLOG_IF_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, condition) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
#else
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATELESS, false && (condition)) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
#endif
|
||||
|
||||
// ABSL_LOG_EVERY_N
|
||||
#define ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
// ABSL_LOG_FIRST_N
|
||||
#define ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
// ABSL_LOG_EVERY_POW_2
|
||||
#define ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
// ABSL_LOG_EVERY_N_SEC
|
||||
#define ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(FirstN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryPow2) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, true)(EveryNSec, n_seconds) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
|
||||
(EveryN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
|
||||
(FirstN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
|
||||
(EveryPow2) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, true) \
|
||||
(EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#else // def NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
|
||||
(EveryN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(severity, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
|
||||
(FirstN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(severity) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
|
||||
(EveryPow2) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO(STATEFUL, false) \
|
||||
(EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
#endif // def NDEBUG
|
||||
|
||||
#define ABSL_LOG_INTERNAL_VLOG_EVERY_N_IMPL(verbose_level, n) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO( \
|
||||
STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
(EveryN, n) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream().WithVerbosity( \
|
||||
absl_logging_internal_verbose_level)
|
||||
|
||||
#define ABSL_LOG_INTERNAL_VLOG_FIRST_N_IMPL(verbose_level, n) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO( \
|
||||
STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
(FirstN, n) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream().WithVerbosity( \
|
||||
absl_logging_internal_verbose_level)
|
||||
|
||||
#define ABSL_LOG_INTERNAL_VLOG_EVERY_POW_2_IMPL(verbose_level) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO( \
|
||||
STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
(EveryPow2) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream().WithVerbosity( \
|
||||
absl_logging_internal_verbose_level)
|
||||
|
||||
#define ABSL_LOG_INTERNAL_VLOG_EVERY_N_SEC_IMPL(verbose_level, n_seconds) \
|
||||
switch (const int absl_logging_internal_verbose_level = (verbose_level)) \
|
||||
case 0: \
|
||||
default: \
|
||||
ABSL_LOG_INTERNAL_CONDITION_INFO( \
|
||||
STATEFUL, ABSL_VLOG_IS_ON(absl_logging_internal_verbose_level)) \
|
||||
(EveryNSec, n_seconds) ABSL_LOGGING_INTERNAL_LOG_INFO.InternalStream() \
|
||||
.WithVerbosity(absl_logging_internal_verbose_level)
|
||||
|
||||
#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
|
||||
n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
|
||||
n_seconds) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
|
||||
n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
|
||||
n_seconds) \
|
||||
ABSL_LOGGING_INTERNAL_LOG##severity.InternalStream() \
|
||||
.WithPerror()
|
||||
|
||||
#ifndef NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryN, n) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(FirstN, n) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryPow2) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
|
||||
n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, condition)(EveryNSec, \
|
||||
n_seconds) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#else // def NDEBUG
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
|
||||
EveryN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
|
||||
FirstN, n) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
|
||||
EveryPow2) ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
|
||||
#define ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(severity, condition, \
|
||||
n_seconds) \
|
||||
ABSL_LOG_INTERNAL_CONDITION##severity(STATEFUL, false && (condition))( \
|
||||
EveryNSec, n_seconds) \
|
||||
ABSL_LOGGING_INTERNAL_DLOG##severity.InternalStream()
|
||||
#endif // def NDEBUG
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_LOG_IMPL_H_
|
||||
742
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_message.cc
Normal file
742
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_message.cc
Normal file
|
|
@ -0,0 +1,742 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/log_message.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <tuple>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/internal/strerror.h"
|
||||
#include "absl/base/internal/sysinfo.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/container/inlined_vector.h"
|
||||
#include "absl/debugging/internal/examine_stack.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/append_truncated.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
#include "absl/log/internal/log_format.h"
|
||||
#include "absl/log/internal/log_sink_set.h"
|
||||
#include "absl/log/internal/proto.h"
|
||||
#include "absl/log/internal/structured_proto.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/log/log_sink_registry.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
|
||||
AbslInternalOnFatalLogMessage)(const absl::LogEntry&) {
|
||||
// Default - Do nothing
|
||||
}
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
namespace {
|
||||
// message `logging.proto.Event`
|
||||
enum EventTag : uint8_t {
|
||||
kFileName = 2,
|
||||
kFileLine = 3,
|
||||
kTimeNsecs = 4,
|
||||
kSeverity = 5,
|
||||
kThreadId = 6,
|
||||
kValue = 7,
|
||||
kSequenceNumber = 9,
|
||||
kThreadName = 10,
|
||||
};
|
||||
|
||||
// message `logging.proto.Value`
|
||||
enum ValueTag : uint8_t {
|
||||
kString = 1,
|
||||
kStringLiteral = 6,
|
||||
};
|
||||
|
||||
// Decodes a `logging.proto.Value` from `buf` and writes a string representation
|
||||
// into `dst`. The string representation will be truncated if `dst` is not
|
||||
// large enough to hold it. Returns false if `dst` has size zero or one (i.e.
|
||||
// sufficient only for a nul-terminator) and no decoded data could be written.
|
||||
// This function may or may not write a nul-terminator into `dst`, and it may or
|
||||
// may not truncate the data it writes in order to do make space for that nul
|
||||
// terminator. In any case, `dst` will be advanced to point at the byte where
|
||||
// subsequent writes should begin.
|
||||
bool PrintValue(absl::Span<char>& dst, absl::Span<const char> buf) {
|
||||
if (dst.size() <= 1) return false;
|
||||
ProtoField field;
|
||||
while (field.DecodeFrom(&buf)) {
|
||||
switch (field.tag()) {
|
||||
case ValueTag::kString:
|
||||
case ValueTag::kStringLiteral:
|
||||
if (field.type() == WireType::kLengthDelimited)
|
||||
if (log_internal::AppendTruncated(field.string_value(), dst) <
|
||||
field.string_value().size())
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// See `logging.proto.Severity`
|
||||
int32_t ProtoSeverity(absl::LogSeverity severity, int verbose_level) {
|
||||
switch (severity) {
|
||||
case absl::LogSeverity::kInfo:
|
||||
if (verbose_level == absl::LogEntry::kNoVerbosityLevel) return 800;
|
||||
return 600 - verbose_level;
|
||||
case absl::LogSeverity::kWarning:
|
||||
return 900;
|
||||
case absl::LogSeverity::kError:
|
||||
return 950;
|
||||
case absl::LogSeverity::kFatal:
|
||||
return 1100;
|
||||
default:
|
||||
return 800;
|
||||
}
|
||||
}
|
||||
|
||||
absl::string_view Basename(absl::string_view filepath) {
|
||||
#ifdef _WIN32
|
||||
size_t path = filepath.find_last_of("/\\");
|
||||
#else
|
||||
size_t path = filepath.find_last_of('/');
|
||||
#endif
|
||||
if (path != filepath.npos) filepath.remove_prefix(path + 1);
|
||||
return filepath;
|
||||
}
|
||||
|
||||
void WriteToString(const char* data, void* str) {
|
||||
reinterpret_cast<std::string*>(str)->append(data);
|
||||
}
|
||||
void WriteToStream(const char* data, void* os) {
|
||||
auto* cast_os = static_cast<std::ostream*>(os);
|
||||
*cast_os << data;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
struct LogMessage::LogMessageData final {
|
||||
LogMessageData(absl::Nonnull<const char*> file, int line,
|
||||
absl::LogSeverity severity, absl::Time timestamp);
|
||||
LogMessageData(const LogMessageData&) = delete;
|
||||
LogMessageData& operator=(const LogMessageData&) = delete;
|
||||
|
||||
// `LogEntry` sent to `LogSink`s; contains metadata.
|
||||
absl::LogEntry entry;
|
||||
|
||||
// true => this was first fatal msg
|
||||
bool first_fatal;
|
||||
// true => all failures should be quiet
|
||||
bool fail_quietly;
|
||||
// true => PLOG was requested
|
||||
bool is_perror;
|
||||
|
||||
// Extra `LogSink`s to log to, in addition to `global_sinks`.
|
||||
absl::InlinedVector<absl::Nonnull<absl::LogSink*>, 16> extra_sinks;
|
||||
// If true, log to `extra_sinks` but not to `global_sinks` or hardcoded
|
||||
// non-sink targets (e.g. stderr, log files).
|
||||
bool extra_sinks_only;
|
||||
|
||||
std::ostream manipulated; // ostream with IO manipulators applied
|
||||
|
||||
// A `logging.proto.Event` proto message is built into `encoded_buf`.
|
||||
std::array<char, kLogMessageBufferSize> encoded_buf;
|
||||
// `encoded_remaining()` is the suffix of `encoded_buf` that has not been
|
||||
// filled yet. If a datum to be encoded does not fit into
|
||||
// `encoded_remaining()` and cannot be truncated to fit, the size of
|
||||
// `encoded_remaining()` will be zeroed to prevent encoding of any further
|
||||
// data. Note that in this case its `data()` pointer will not point past the
|
||||
// end of `encoded_buf`.
|
||||
// The first use of `encoded_remaining()` is our chance to record metadata
|
||||
// after any modifications (e.g. by `AtLocation()`) but before any data have
|
||||
// been recorded. We want to record metadata before data so that data are
|
||||
// preferentially truncated if we run out of buffer.
|
||||
absl::Span<char>& encoded_remaining() {
|
||||
if (encoded_remaining_actual_do_not_use_directly.data() == nullptr) {
|
||||
encoded_remaining_actual_do_not_use_directly =
|
||||
absl::MakeSpan(encoded_buf);
|
||||
InitializeEncodingAndFormat();
|
||||
}
|
||||
return encoded_remaining_actual_do_not_use_directly;
|
||||
}
|
||||
absl::Span<char> encoded_remaining_actual_do_not_use_directly;
|
||||
|
||||
// A formatted string message is built in `string_buf`.
|
||||
std::array<char, kLogMessageBufferSize> string_buf;
|
||||
|
||||
void InitializeEncodingAndFormat();
|
||||
void FinalizeEncodingAndFormat();
|
||||
};
|
||||
|
||||
LogMessage::LogMessageData::LogMessageData(absl::Nonnull<const char*> file,
|
||||
int line, absl::LogSeverity severity,
|
||||
absl::Time timestamp)
|
||||
: extra_sinks_only(false), manipulated(nullptr) {
|
||||
// Legacy defaults for LOG's ostream:
|
||||
manipulated.setf(std::ios_base::showbase | std::ios_base::boolalpha);
|
||||
entry.full_filename_ = file;
|
||||
entry.base_filename_ = Basename(file);
|
||||
entry.line_ = line;
|
||||
entry.prefix_ = absl::ShouldPrependLogPrefix();
|
||||
entry.severity_ = absl::NormalizeLogSeverity(severity);
|
||||
entry.verbose_level_ = absl::LogEntry::kNoVerbosityLevel;
|
||||
entry.timestamp_ = timestamp;
|
||||
entry.tid_ = absl::base_internal::GetCachedTID();
|
||||
}
|
||||
|
||||
void LogMessage::LogMessageData::InitializeEncodingAndFormat() {
|
||||
EncodeStringTruncate(EventTag::kFileName, entry.source_filename(),
|
||||
&encoded_remaining());
|
||||
EncodeVarint(EventTag::kFileLine, entry.source_line(), &encoded_remaining());
|
||||
EncodeVarint(EventTag::kTimeNsecs, absl::ToUnixNanos(entry.timestamp()),
|
||||
&encoded_remaining());
|
||||
EncodeVarint(EventTag::kSeverity,
|
||||
ProtoSeverity(entry.log_severity(), entry.verbosity()),
|
||||
&encoded_remaining());
|
||||
EncodeVarint(EventTag::kThreadId, entry.tid(), &encoded_remaining());
|
||||
}
|
||||
|
||||
void LogMessage::LogMessageData::FinalizeEncodingAndFormat() {
|
||||
// Note that `encoded_remaining()` may have zero size without pointing past
|
||||
// the end of `encoded_buf`, so the difference between `data()` pointers is
|
||||
// used to compute the size of `encoded_data`.
|
||||
absl::Span<const char> encoded_data(
|
||||
encoded_buf.data(),
|
||||
static_cast<size_t>(encoded_remaining().data() - encoded_buf.data()));
|
||||
// `string_remaining` is the suffix of `string_buf` that has not been filled
|
||||
// yet.
|
||||
absl::Span<char> string_remaining(string_buf);
|
||||
// We may need to write a newline and nul-terminator at the end of the decoded
|
||||
// string data. Rather than worry about whether those should overwrite the
|
||||
// end of the string (if the buffer is full) or be appended, we avoid writing
|
||||
// into the last two bytes so we always have space to append.
|
||||
string_remaining.remove_suffix(2);
|
||||
entry.prefix_len_ =
|
||||
entry.prefix() ? log_internal::FormatLogPrefix(
|
||||
entry.log_severity(), entry.timestamp(), entry.tid(),
|
||||
entry.source_basename(), entry.source_line(),
|
||||
log_internal::ThreadIsLoggingToLogSink()
|
||||
? PrefixFormat::kRaw
|
||||
: PrefixFormat::kNotRaw,
|
||||
string_remaining)
|
||||
: 0;
|
||||
// Decode data from `encoded_buf` until we run out of data or we run out of
|
||||
// `string_remaining`.
|
||||
ProtoField field;
|
||||
while (field.DecodeFrom(&encoded_data)) {
|
||||
switch (field.tag()) {
|
||||
case EventTag::kValue:
|
||||
if (field.type() != WireType::kLengthDelimited) continue;
|
||||
if (PrintValue(string_remaining, field.bytes_value())) continue;
|
||||
break;
|
||||
}
|
||||
}
|
||||
auto chars_written =
|
||||
static_cast<size_t>(string_remaining.data() - string_buf.data());
|
||||
string_buf[chars_written++] = '\n';
|
||||
string_buf[chars_written++] = '\0';
|
||||
entry.text_message_with_prefix_and_newline_and_nul_ =
|
||||
absl::MakeSpan(string_buf).subspan(0, chars_written);
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(absl::Nonnull<const char*> file, int line,
|
||||
absl::LogSeverity severity)
|
||||
: data_(absl::make_unique<LogMessageData>(file, line, severity,
|
||||
absl::Now())) {
|
||||
data_->first_fatal = false;
|
||||
data_->is_perror = false;
|
||||
data_->fail_quietly = false;
|
||||
|
||||
// This logs a backtrace even if the location is subsequently changed using
|
||||
// AtLocation. This quirk, and the behavior when AtLocation is called twice,
|
||||
// are fixable but probably not worth fixing.
|
||||
LogBacktraceIfNeeded();
|
||||
}
|
||||
|
||||
LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, InfoTag)
|
||||
: LogMessage(file, line, absl::LogSeverity::kInfo) {}
|
||||
LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, WarningTag)
|
||||
: LogMessage(file, line, absl::LogSeverity::kWarning) {}
|
||||
LogMessage::LogMessage(absl::Nonnull<const char*> file, int line, ErrorTag)
|
||||
: LogMessage(file, line, absl::LogSeverity::kError) {}
|
||||
|
||||
LogMessage::~LogMessage() {
|
||||
#ifdef ABSL_MIN_LOG_LEVEL
|
||||
if (data_->entry.log_severity() <
|
||||
static_cast<absl::LogSeverity>(ABSL_MIN_LOG_LEVEL) &&
|
||||
data_->entry.log_severity() < absl::LogSeverity::kFatal) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
Flush();
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::AtLocation(absl::string_view file, int line) {
|
||||
data_->entry.full_filename_ = file;
|
||||
data_->entry.base_filename_ = Basename(file);
|
||||
data_->entry.line_ = line;
|
||||
LogBacktraceIfNeeded();
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::NoPrefix() {
|
||||
data_->entry.prefix_ = false;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::WithVerbosity(int verbose_level) {
|
||||
if (verbose_level == absl::LogEntry::kNoVerbosityLevel) {
|
||||
data_->entry.verbose_level_ = absl::LogEntry::kNoVerbosityLevel;
|
||||
} else {
|
||||
data_->entry.verbose_level_ = std::max(0, verbose_level);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::WithTimestamp(absl::Time timestamp) {
|
||||
data_->entry.timestamp_ = timestamp;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::WithThreadID(absl::LogEntry::tid_t tid) {
|
||||
data_->entry.tid_ = tid;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::WithMetadataFrom(const absl::LogEntry& entry) {
|
||||
data_->entry.full_filename_ = entry.full_filename_;
|
||||
data_->entry.base_filename_ = entry.base_filename_;
|
||||
data_->entry.line_ = entry.line_;
|
||||
data_->entry.prefix_ = entry.prefix_;
|
||||
data_->entry.severity_ = entry.severity_;
|
||||
data_->entry.verbose_level_ = entry.verbose_level_;
|
||||
data_->entry.timestamp_ = entry.timestamp_;
|
||||
data_->entry.tid_ = entry.tid_;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::WithPerror() {
|
||||
data_->is_perror = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::ToSinkAlso(absl::Nonnull<absl::LogSink*> sink) {
|
||||
ABSL_INTERNAL_CHECK(sink, "null LogSink*");
|
||||
data_->extra_sinks.push_back(sink);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::ToSinkOnly(absl::Nonnull<absl::LogSink*> sink) {
|
||||
ABSL_INTERNAL_CHECK(sink, "null LogSink*");
|
||||
data_->extra_sinks.clear();
|
||||
data_->extra_sinks.push_back(sink);
|
||||
data_->extra_sinks_only = true;
|
||||
return *this;
|
||||
}
|
||||
|
||||
#ifdef __ELF__
|
||||
extern "C" void __gcov_dump() ABSL_ATTRIBUTE_WEAK;
|
||||
extern "C" void __gcov_flush() ABSL_ATTRIBUTE_WEAK;
|
||||
#endif
|
||||
|
||||
void LogMessage::FailWithoutStackTrace() {
|
||||
// Now suppress repeated trace logging:
|
||||
log_internal::SetSuppressSigabortTrace(true);
|
||||
#if defined _DEBUG && defined COMPILER_MSVC
|
||||
// When debugging on windows, avoid the obnoxious dialog.
|
||||
__debugbreak();
|
||||
#endif
|
||||
|
||||
#ifdef __ELF__
|
||||
// For b/8737634, flush coverage if we are in coverage mode.
|
||||
if (&__gcov_dump != nullptr) {
|
||||
__gcov_dump();
|
||||
} else if (&__gcov_flush != nullptr) {
|
||||
__gcov_flush();
|
||||
}
|
||||
#endif
|
||||
|
||||
abort();
|
||||
}
|
||||
|
||||
void LogMessage::FailQuietly() {
|
||||
// _exit. Calling abort() would trigger all sorts of death signal handlers
|
||||
// and a detailed stack trace. Calling exit() would trigger the onexit
|
||||
// handlers, including the heap-leak checker, which is guaranteed to fail in
|
||||
// this case: we probably just new'ed the std::string that we logged.
|
||||
// Anyway, if you're calling Fail or FailQuietly, you're trying to bail out
|
||||
// of the program quickly, and it doesn't make much sense for FailQuietly to
|
||||
// offer different guarantees about exit behavior than Fail does. (And as a
|
||||
// consequence for QCHECK and CHECK to offer different exit behaviors)
|
||||
_exit(1);
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::operator<<(const std::string& v) {
|
||||
CopyToEncodedBuffer<StringType::kNotLiteral>(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
LogMessage& LogMessage::operator<<(absl::string_view v) {
|
||||
CopyToEncodedBuffer<StringType::kNotLiteral>(v);
|
||||
return *this;
|
||||
}
|
||||
LogMessage& LogMessage::operator<<(std::ostream& (*m)(std::ostream& os)) {
|
||||
OstreamView view(*data_);
|
||||
data_->manipulated << m;
|
||||
return *this;
|
||||
}
|
||||
LogMessage& LogMessage::operator<<(std::ios_base& (*m)(std::ios_base& os)) {
|
||||
OstreamView view(*data_);
|
||||
data_->manipulated << m;
|
||||
return *this;
|
||||
}
|
||||
// NOLINTBEGIN(runtime/int)
|
||||
// NOLINTBEGIN(google-runtime-int)
|
||||
template LogMessage& LogMessage::operator<<(const char& v);
|
||||
template LogMessage& LogMessage::operator<<(const signed char& v);
|
||||
template LogMessage& LogMessage::operator<<(const unsigned char& v);
|
||||
template LogMessage& LogMessage::operator<<(const short& v);
|
||||
template LogMessage& LogMessage::operator<<(const unsigned short& v);
|
||||
template LogMessage& LogMessage::operator<<(const int& v);
|
||||
template LogMessage& LogMessage::operator<<(const unsigned int& v);
|
||||
template LogMessage& LogMessage::operator<<(const long& v);
|
||||
template LogMessage& LogMessage::operator<<(const unsigned long& v);
|
||||
template LogMessage& LogMessage::operator<<(const long long& v);
|
||||
template LogMessage& LogMessage::operator<<(const unsigned long long& v);
|
||||
template LogMessage& LogMessage::operator<<(void* const& v);
|
||||
template LogMessage& LogMessage::operator<<(const void* const& v);
|
||||
template LogMessage& LogMessage::operator<<(const float& v);
|
||||
template LogMessage& LogMessage::operator<<(const double& v);
|
||||
template LogMessage& LogMessage::operator<<(const bool& v);
|
||||
// NOLINTEND(google-runtime-int)
|
||||
// NOLINTEND(runtime/int)
|
||||
|
||||
void LogMessage::Flush() {
|
||||
if (data_->entry.log_severity() < absl::MinLogLevel()) return;
|
||||
|
||||
if (data_->is_perror) {
|
||||
InternalStream() << ": " << absl::base_internal::StrError(errno_saver_())
|
||||
<< " [" << errno_saver_() << "]";
|
||||
}
|
||||
|
||||
// Have we already seen a fatal message?
|
||||
ABSL_CONST_INIT static std::atomic<bool> seen_fatal(false);
|
||||
if (data_->entry.log_severity() == absl::LogSeverity::kFatal &&
|
||||
absl::log_internal::ExitOnDFatal()) {
|
||||
// Exactly one LOG(FATAL) message is responsible for aborting the process,
|
||||
// even if multiple threads LOG(FATAL) concurrently.
|
||||
bool expected_seen_fatal = false;
|
||||
if (seen_fatal.compare_exchange_strong(expected_seen_fatal, true,
|
||||
std::memory_order_relaxed)) {
|
||||
data_->first_fatal = true;
|
||||
}
|
||||
}
|
||||
|
||||
data_->FinalizeEncodingAndFormat();
|
||||
data_->entry.encoding_ =
|
||||
absl::string_view(data_->encoded_buf.data(),
|
||||
static_cast<size_t>(data_->encoded_remaining().data() -
|
||||
data_->encoded_buf.data()));
|
||||
SendToLog();
|
||||
}
|
||||
|
||||
void LogMessage::SetFailQuietly() { data_->fail_quietly = true; }
|
||||
|
||||
LogMessage::OstreamView::OstreamView(LogMessageData& message_data)
|
||||
: data_(message_data), encoded_remaining_copy_(data_.encoded_remaining()) {
|
||||
// This constructor sets the `streambuf` up so that streaming into an attached
|
||||
// ostream encodes string data in-place. To do that, we write appropriate
|
||||
// headers into the buffer using a copy of the buffer view so that we can
|
||||
// decide not to keep them later if nothing is ever streamed in. We don't
|
||||
// know how much data we'll get, but we can use the size of the remaining
|
||||
// buffer as an upper bound and fill in the right size once we know it.
|
||||
message_start_ =
|
||||
EncodeMessageStart(EventTag::kValue, encoded_remaining_copy_.size(),
|
||||
&encoded_remaining_copy_);
|
||||
string_start_ =
|
||||
EncodeMessageStart(ValueTag::kString, encoded_remaining_copy_.size(),
|
||||
&encoded_remaining_copy_);
|
||||
setp(encoded_remaining_copy_.data(),
|
||||
encoded_remaining_copy_.data() + encoded_remaining_copy_.size());
|
||||
data_.manipulated.rdbuf(this);
|
||||
}
|
||||
|
||||
LogMessage::OstreamView::~OstreamView() {
|
||||
data_.manipulated.rdbuf(nullptr);
|
||||
if (!string_start_.data()) {
|
||||
// The second field header didn't fit. Whether the first one did or not, we
|
||||
// shouldn't commit `encoded_remaining_copy_`, and we also need to zero the
|
||||
// size of `data_->encoded_remaining()` so that no more data are encoded.
|
||||
data_.encoded_remaining().remove_suffix(data_.encoded_remaining().size());
|
||||
return;
|
||||
}
|
||||
const absl::Span<const char> contents(pbase(),
|
||||
static_cast<size_t>(pptr() - pbase()));
|
||||
if (contents.empty()) return;
|
||||
encoded_remaining_copy_.remove_prefix(contents.size());
|
||||
EncodeMessageLength(string_start_, &encoded_remaining_copy_);
|
||||
EncodeMessageLength(message_start_, &encoded_remaining_copy_);
|
||||
data_.encoded_remaining() = encoded_remaining_copy_;
|
||||
}
|
||||
|
||||
std::ostream& LogMessage::OstreamView::stream() { return data_.manipulated; }
|
||||
|
||||
bool LogMessage::IsFatal() const {
|
||||
return data_->entry.log_severity() == absl::LogSeverity::kFatal &&
|
||||
absl::log_internal::ExitOnDFatal();
|
||||
}
|
||||
|
||||
void LogMessage::PrepareToDie() {
|
||||
// If we log a FATAL message, flush all the log destinations, then toss
|
||||
// a signal for others to catch. We leave the logs in a state that
|
||||
// someone else can use them (as long as they flush afterwards)
|
||||
if (data_->first_fatal) {
|
||||
// Notify observers about the upcoming fatal error.
|
||||
ABSL_INTERNAL_C_SYMBOL(AbslInternalOnFatalLogMessage)(data_->entry);
|
||||
}
|
||||
|
||||
if (!data_->fail_quietly) {
|
||||
// Log the message first before we start collecting stack trace.
|
||||
log_internal::LogToSinks(data_->entry, absl::MakeSpan(data_->extra_sinks),
|
||||
data_->extra_sinks_only);
|
||||
|
||||
// `DumpStackTrace` generates an empty string under MSVC.
|
||||
// Adding the constant prefix here simplifies testing.
|
||||
data_->entry.stacktrace_ = "*** Check failure stack trace: ***\n";
|
||||
debugging_internal::DumpStackTrace(
|
||||
0, log_internal::MaxFramesInLogStackTrace(),
|
||||
log_internal::ShouldSymbolizeLogStackTrace(), WriteToString,
|
||||
&data_->entry.stacktrace_);
|
||||
}
|
||||
}
|
||||
|
||||
void LogMessage::Die() {
|
||||
absl::FlushLogSinks();
|
||||
|
||||
if (data_->fail_quietly) {
|
||||
FailQuietly();
|
||||
} else {
|
||||
FailWithoutStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
void LogMessage::SendToLog() {
|
||||
if (IsFatal()) PrepareToDie();
|
||||
// Also log to all registered sinks, even if OnlyLogToStderr() is set.
|
||||
log_internal::LogToSinks(data_->entry, absl::MakeSpan(data_->extra_sinks),
|
||||
data_->extra_sinks_only);
|
||||
if (IsFatal()) Die();
|
||||
}
|
||||
|
||||
void LogMessage::LogBacktraceIfNeeded() {
|
||||
if (!absl::log_internal::IsInitialized()) return;
|
||||
|
||||
if (!absl::log_internal::ShouldLogBacktraceAt(data_->entry.source_basename(),
|
||||
data_->entry.source_line()))
|
||||
return;
|
||||
OstreamView view(*data_);
|
||||
view.stream() << " (stacktrace:\n";
|
||||
debugging_internal::DumpStackTrace(
|
||||
1, log_internal::MaxFramesInLogStackTrace(),
|
||||
log_internal::ShouldSymbolizeLogStackTrace(), WriteToStream,
|
||||
&view.stream());
|
||||
view.stream() << ") ";
|
||||
}
|
||||
|
||||
// Encodes into `data_->encoded_remaining()` a partial `logging.proto.Event`
|
||||
// containing the specified string data using a `Value` field appropriate to
|
||||
// `str_type`. Truncates `str` if necessary, but emits nothing and marks the
|
||||
// buffer full if even the field headers do not fit.
|
||||
template <LogMessage::StringType str_type>
|
||||
void LogMessage::CopyToEncodedBuffer(absl::string_view str) {
|
||||
auto encoded_remaining_copy = data_->encoded_remaining();
|
||||
constexpr uint8_t tag_value = str_type == StringType::kLiteral
|
||||
? ValueTag::kStringLiteral
|
||||
: ValueTag::kString;
|
||||
auto start = EncodeMessageStart(
|
||||
EventTag::kValue,
|
||||
BufferSizeFor(tag_value, WireType::kLengthDelimited) + str.size(),
|
||||
&encoded_remaining_copy);
|
||||
// If the `logging.proto.Event.value` field header did not fit,
|
||||
// `EncodeMessageStart` will have zeroed `encoded_remaining_copy`'s size and
|
||||
// `EncodeStringTruncate` will fail too.
|
||||
if (EncodeStringTruncate(tag_value, str, &encoded_remaining_copy)) {
|
||||
// The string may have been truncated, but the field header fit.
|
||||
EncodeMessageLength(start, &encoded_remaining_copy);
|
||||
data_->encoded_remaining() = encoded_remaining_copy;
|
||||
} else {
|
||||
// The field header(s) did not fit; zero `encoded_remaining()` so we don't
|
||||
// write anything else later.
|
||||
data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
|
||||
}
|
||||
}
|
||||
template void LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(
|
||||
absl::string_view str);
|
||||
template void LogMessage::CopyToEncodedBuffer<
|
||||
LogMessage::StringType::kNotLiteral>(absl::string_view str);
|
||||
template <LogMessage::StringType str_type>
|
||||
void LogMessage::CopyToEncodedBuffer(char ch, size_t num) {
|
||||
auto encoded_remaining_copy = data_->encoded_remaining();
|
||||
constexpr uint8_t tag_value = str_type == StringType::kLiteral
|
||||
? ValueTag::kStringLiteral
|
||||
: ValueTag::kString;
|
||||
auto value_start = EncodeMessageStart(
|
||||
EventTag::kValue,
|
||||
BufferSizeFor(tag_value, WireType::kLengthDelimited) + num,
|
||||
&encoded_remaining_copy);
|
||||
auto str_start = EncodeMessageStart(tag_value, num, &encoded_remaining_copy);
|
||||
if (str_start.data()) {
|
||||
// The field headers fit.
|
||||
log_internal::AppendTruncated(ch, num, encoded_remaining_copy);
|
||||
EncodeMessageLength(str_start, &encoded_remaining_copy);
|
||||
EncodeMessageLength(value_start, &encoded_remaining_copy);
|
||||
data_->encoded_remaining() = encoded_remaining_copy;
|
||||
} else {
|
||||
// The field header(s) did not fit; zero `encoded_remaining()` so we don't
|
||||
// write anything else later.
|
||||
data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
|
||||
}
|
||||
}
|
||||
template void LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(
|
||||
char ch, size_t num);
|
||||
template void LogMessage::CopyToEncodedBuffer<
|
||||
LogMessage::StringType::kNotLiteral>(char ch, size_t num);
|
||||
|
||||
template void LogMessage::CopyToEncodedBufferWithStructuredProtoField<
|
||||
LogMessage::StringType::kLiteral>(StructuredProtoField field,
|
||||
absl::string_view str);
|
||||
template void LogMessage::CopyToEncodedBufferWithStructuredProtoField<
|
||||
LogMessage::StringType::kNotLiteral>(StructuredProtoField field,
|
||||
absl::string_view str);
|
||||
|
||||
template <LogMessage::StringType str_type>
|
||||
void LogMessage::CopyToEncodedBufferWithStructuredProtoField(
|
||||
StructuredProtoField field, absl::string_view str) {
|
||||
auto encoded_remaining_copy = data_->encoded_remaining();
|
||||
size_t encoded_field_size = BufferSizeForStructuredProtoField(field);
|
||||
constexpr uint8_t tag_value = str_type == StringType::kLiteral
|
||||
? ValueTag::kStringLiteral
|
||||
: ValueTag::kString;
|
||||
auto start = EncodeMessageStart(
|
||||
EventTag::kValue,
|
||||
encoded_field_size +
|
||||
BufferSizeFor(tag_value, WireType::kLengthDelimited) + str.size(),
|
||||
&encoded_remaining_copy);
|
||||
|
||||
// Write the encoded proto field.
|
||||
if (!EncodeStructuredProtoField(field, encoded_remaining_copy)) {
|
||||
// The header / field will not fit; zero `encoded_remaining()` so we
|
||||
// don't write anything else later.
|
||||
data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
|
||||
return;
|
||||
}
|
||||
|
||||
// Write the string, truncating if necessary.
|
||||
if (!EncodeStringTruncate(ValueTag::kString, str, &encoded_remaining_copy)) {
|
||||
// The length of the string itself did not fit; zero `encoded_remaining()`
|
||||
// so the value is not encoded at all.
|
||||
data_->encoded_remaining().remove_suffix(data_->encoded_remaining().size());
|
||||
return;
|
||||
}
|
||||
|
||||
EncodeMessageLength(start, &encoded_remaining_copy);
|
||||
data_->encoded_remaining() = encoded_remaining_copy;
|
||||
}
|
||||
|
||||
// We intentionally don't return from these destructors. Disable MSVC's warning
|
||||
// about the destructor never returning as we do so intentionally here.
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable : 4722)
|
||||
#endif
|
||||
|
||||
LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line)
|
||||
: LogMessage(file, line, absl::LogSeverity::kFatal) {}
|
||||
|
||||
LogMessageFatal::LogMessageFatal(absl::Nonnull<const char*> file, int line,
|
||||
absl::Nonnull<const char*> failure_msg)
|
||||
: LogMessage(file, line, absl::LogSeverity::kFatal) {
|
||||
*this << "Check failed: " << failure_msg << " ";
|
||||
}
|
||||
|
||||
LogMessageFatal::~LogMessageFatal() {
|
||||
Flush();
|
||||
FailWithoutStackTrace();
|
||||
}
|
||||
|
||||
LogMessageDebugFatal::LogMessageDebugFatal(absl::Nonnull<const char*> file,
|
||||
int line)
|
||||
: LogMessage(file, line, absl::LogSeverity::kFatal) {}
|
||||
|
||||
LogMessageDebugFatal::~LogMessageDebugFatal() {
|
||||
Flush();
|
||||
FailWithoutStackTrace();
|
||||
}
|
||||
|
||||
LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal(
|
||||
absl::Nonnull<const char*> file, int line)
|
||||
: LogMessage(file, line, absl::LogSeverity::kFatal) {
|
||||
SetFailQuietly();
|
||||
}
|
||||
|
||||
LogMessageQuietlyDebugFatal::~LogMessageQuietlyDebugFatal() {
|
||||
Flush();
|
||||
FailQuietly();
|
||||
}
|
||||
|
||||
LogMessageQuietlyFatal::LogMessageQuietlyFatal(absl::Nonnull<const char*> file,
|
||||
int line)
|
||||
: LogMessage(file, line, absl::LogSeverity::kFatal) {
|
||||
SetFailQuietly();
|
||||
}
|
||||
|
||||
LogMessageQuietlyFatal::LogMessageQuietlyFatal(
|
||||
absl::Nonnull<const char*> file, int line,
|
||||
absl::Nonnull<const char*> failure_msg)
|
||||
: LogMessageQuietlyFatal(file, line) {
|
||||
*this << "Check failed: " << failure_msg << " ";
|
||||
}
|
||||
|
||||
LogMessageQuietlyFatal::~LogMessageQuietlyFatal() {
|
||||
Flush();
|
||||
FailQuietly();
|
||||
}
|
||||
#if defined(_MSC_VER) && !defined(__clang__)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
426
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_message.h
Normal file
426
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_message.h
Normal file
|
|
@ -0,0 +1,426 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/log_message.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file declares `class absl::log_internal::LogMessage`. This class more or
|
||||
// less represents a particular log message. LOG/CHECK macros create a
|
||||
// temporary instance of `LogMessage` and then stream values to it. At the end
|
||||
// of the LOG/CHECK statement, LogMessage instance goes out of scope and
|
||||
// `~LogMessage` directs the message to the registered log sinks.
|
||||
// Heap-allocation of `LogMessage` is unsupported. Construction outside of a
|
||||
// `LOG` macro is unsupported.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
|
||||
#define ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <streambuf>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/errno_saver.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/log/internal/nullguard.h"
|
||||
#include "absl/log/internal/structured_proto.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/strings/has_absl_stringify.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
constexpr int kLogMessageBufferSize = 15000;
|
||||
|
||||
enum class StructuredStringType;
|
||||
|
||||
class LogMessage {
|
||||
public:
|
||||
struct InfoTag {};
|
||||
struct WarningTag {};
|
||||
struct ErrorTag {};
|
||||
|
||||
// Used for `LOG`.
|
||||
LogMessage(absl::Nonnull<const char*> file, int line,
|
||||
absl::LogSeverity severity) ABSL_ATTRIBUTE_COLD;
|
||||
// These constructors are slightly smaller/faster to call; the severity is
|
||||
// curried into the function pointer.
|
||||
LogMessage(absl::Nonnull<const char*> file, int line,
|
||||
InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
|
||||
LogMessage(absl::Nonnull<const char*> file, int line,
|
||||
WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
|
||||
LogMessage(absl::Nonnull<const char*> file, int line,
|
||||
ErrorTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
|
||||
LogMessage(const LogMessage&) = delete;
|
||||
LogMessage& operator=(const LogMessage&) = delete;
|
||||
~LogMessage() ABSL_ATTRIBUTE_COLD;
|
||||
|
||||
// Overrides the location inferred from the callsite. The string pointed to
|
||||
// by `file` must be valid until the end of the statement.
|
||||
LogMessage& AtLocation(absl::string_view file, int line);
|
||||
// Omits the prefix from this line. The prefix includes metadata about the
|
||||
// logged data such as source code location and timestamp.
|
||||
LogMessage& NoPrefix();
|
||||
// Sets the verbosity field of the logged message as if it was logged by
|
||||
// `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect
|
||||
// evaluation of the statement when the specified `verbose_level` has been
|
||||
// disabled. The only effect is on `absl::LogSink` implementations which
|
||||
// make use of the `absl::LogSink::verbosity()` value. The value
|
||||
// `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message
|
||||
// not verbose.
|
||||
LogMessage& WithVerbosity(int verbose_level);
|
||||
// Uses the specified timestamp instead of one collected in the constructor.
|
||||
LogMessage& WithTimestamp(absl::Time timestamp);
|
||||
// Uses the specified thread ID instead of one collected in the constructor.
|
||||
LogMessage& WithThreadID(absl::LogEntry::tid_t tid);
|
||||
// Copies all metadata (but no data) from the specified `absl::LogEntry`.
|
||||
LogMessage& WithMetadataFrom(const absl::LogEntry& entry);
|
||||
// Appends to the logged message a colon, a space, a textual description of
|
||||
// the current value of `errno` (as by strerror(3)), and the numerical value
|
||||
// of `errno`.
|
||||
LogMessage& WithPerror();
|
||||
// Sends this message to `*sink` in addition to whatever other sinks it would
|
||||
// otherwise have been sent to.
|
||||
LogMessage& ToSinkAlso(absl::Nonnull<absl::LogSink*> sink);
|
||||
// Sends this message to `*sink` and no others.
|
||||
LogMessage& ToSinkOnly(absl::Nonnull<absl::LogSink*> sink);
|
||||
|
||||
// Don't call this method from outside this library.
|
||||
LogMessage& InternalStream() { return *this; }
|
||||
|
||||
// By-value overloads for small, common types let us overlook common failures
|
||||
// to define globals and static data members (i.e. in a .cc file).
|
||||
// NOLINTBEGIN(runtime/int)
|
||||
// NOLINTBEGIN(google-runtime-int)
|
||||
// clang-format off: The CUDA toolchain cannot handle these <<<'s
|
||||
LogMessage& operator<<(char v) { return operator<< <char>(v); }
|
||||
LogMessage& operator<<(signed char v) { return operator<< <signed char>(v); }
|
||||
LogMessage& operator<<(unsigned char v) {
|
||||
return operator<< <unsigned char>(v);
|
||||
}
|
||||
LogMessage& operator<<(signed short v) {
|
||||
return operator<< <signed short>(v);
|
||||
}
|
||||
LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); }
|
||||
LogMessage& operator<<(signed long v) {
|
||||
return operator<< <signed long>(v);
|
||||
}
|
||||
LogMessage& operator<<(signed long long v) {
|
||||
return operator<< <signed long long>(v);
|
||||
}
|
||||
LogMessage& operator<<(unsigned short v) {
|
||||
return operator<< <unsigned short>(v);
|
||||
}
|
||||
LogMessage& operator<<(unsigned int v) {
|
||||
return operator<< <unsigned int>(v);
|
||||
}
|
||||
LogMessage& operator<<(unsigned long v) {
|
||||
return operator<< <unsigned long>(v);
|
||||
}
|
||||
LogMessage& operator<<(unsigned long long v) {
|
||||
return operator<< <unsigned long long>(v);
|
||||
}
|
||||
LogMessage& operator<<(absl::Nullable<void*> v) {
|
||||
return operator<< <void*>(v);
|
||||
}
|
||||
LogMessage& operator<<(absl::Nullable<const void*> v) {
|
||||
return operator<< <const void*>(v);
|
||||
}
|
||||
LogMessage& operator<<(float v) { return operator<< <float>(v); }
|
||||
LogMessage& operator<<(double v) { return operator<< <double>(v); }
|
||||
LogMessage& operator<<(bool v) { return operator<< <bool>(v); }
|
||||
// clang-format on
|
||||
// NOLINTEND(google-runtime-int)
|
||||
// NOLINTEND(runtime/int)
|
||||
|
||||
// These overloads are more efficient since no `ostream` is involved.
|
||||
LogMessage& operator<<(const std::string& v);
|
||||
LogMessage& operator<<(absl::string_view v);
|
||||
|
||||
// Handle stream manipulators e.g. std::endl.
|
||||
LogMessage& operator<<(absl::Nonnull<std::ostream& (*)(std::ostream & os)> m);
|
||||
LogMessage& operator<<(
|
||||
absl::Nonnull<std::ios_base& (*)(std::ios_base & os)> m);
|
||||
|
||||
// Literal strings. This allows us to record C string literals as literals in
|
||||
// the logging.proto.Value.
|
||||
//
|
||||
// Allow this overload to be inlined to prevent generating instantiations of
|
||||
// this template for every value of `SIZE` encountered in each source code
|
||||
// file. That significantly increases linker input sizes. Inlining is cheap
|
||||
// because the argument to this overload is almost always a string literal so
|
||||
// the call to `strlen` can be replaced at compile time. The overload for
|
||||
// `char[]` below should not be inlined. The compiler typically does not have
|
||||
// the string at compile time and cannot replace the call to `strlen` so
|
||||
// inlining it increases the binary size. See the discussion on
|
||||
// cl/107527369.
|
||||
template <int SIZE>
|
||||
LogMessage& operator<<(const char (&buf)[SIZE]);
|
||||
|
||||
// This prevents non-const `char[]` arrays from looking like literals.
|
||||
template <int SIZE>
|
||||
LogMessage& operator<<(char (&buf)[SIZE]) ABSL_ATTRIBUTE_NOINLINE;
|
||||
|
||||
// Types that support `AbslStringify()` are serialized that way.
|
||||
template <typename T,
|
||||
typename std::enable_if<absl::HasAbslStringify<T>::value,
|
||||
int>::type = 0>
|
||||
LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
|
||||
|
||||
// Types that don't support `AbslStringify()` but do support streaming into a
|
||||
// `std::ostream&` are serialized that way.
|
||||
template <typename T,
|
||||
typename std::enable_if<!absl::HasAbslStringify<T>::value,
|
||||
int>::type = 0>
|
||||
LogMessage& operator<<(const T& v) ABSL_ATTRIBUTE_NOINLINE;
|
||||
|
||||
// Note: We explicitly do not support `operator<<` for non-const references
|
||||
// because it breaks logging of non-integer bitfield types (i.e., enums).
|
||||
|
||||
protected:
|
||||
// Call `abort()` or similar to perform `LOG(FATAL)` crash. It is assumed
|
||||
// that the caller has already generated and written the trace as appropriate.
|
||||
[[noreturn]] static void FailWithoutStackTrace();
|
||||
|
||||
// Similar to `FailWithoutStackTrace()`, but without `abort()`. Terminates
|
||||
// the process with an error exit code.
|
||||
[[noreturn]] static void FailQuietly();
|
||||
|
||||
// Dispatches the completed `absl::LogEntry` to applicable `absl::LogSink`s.
|
||||
// This might as well be inlined into `~LogMessage` except that
|
||||
// `~LogMessageFatal` needs to call it early.
|
||||
void Flush();
|
||||
|
||||
// After this is called, failures are done as quiet as possible for this log
|
||||
// message.
|
||||
void SetFailQuietly();
|
||||
|
||||
private:
|
||||
struct LogMessageData; // Opaque type containing message state
|
||||
friend class AsLiteralImpl;
|
||||
friend class StringifySink;
|
||||
template <StructuredStringType str_type>
|
||||
friend class AsStructuredStringTypeImpl;
|
||||
template <typename T>
|
||||
friend class AsStructuredValueImpl;
|
||||
|
||||
// This streambuf writes directly into the structured logging buffer so that
|
||||
// arbitrary types can be encoded as string data (using
|
||||
// `operator<<(std::ostream &, ...)` without any extra allocation or copying.
|
||||
// Space is reserved before the data to store the length field, which is
|
||||
// filled in by `~OstreamView`.
|
||||
class OstreamView final : public std::streambuf {
|
||||
public:
|
||||
explicit OstreamView(LogMessageData& message_data);
|
||||
~OstreamView() override;
|
||||
OstreamView(const OstreamView&) = delete;
|
||||
OstreamView& operator=(const OstreamView&) = delete;
|
||||
std::ostream& stream();
|
||||
|
||||
private:
|
||||
LogMessageData& data_;
|
||||
absl::Span<char> encoded_remaining_copy_;
|
||||
absl::Span<char> message_start_;
|
||||
absl::Span<char> string_start_;
|
||||
};
|
||||
|
||||
enum class StringType {
|
||||
kLiteral,
|
||||
kNotLiteral,
|
||||
};
|
||||
template <StringType str_type>
|
||||
void CopyToEncodedBuffer(absl::string_view str) ABSL_ATTRIBUTE_NOINLINE;
|
||||
template <StringType str_type>
|
||||
void CopyToEncodedBuffer(char ch, size_t num) ABSL_ATTRIBUTE_NOINLINE;
|
||||
|
||||
// Copies `field` to the encoded buffer, then appends `str` after it
|
||||
// (truncating `str` if necessary to fit).
|
||||
template <StringType str_type>
|
||||
void CopyToEncodedBufferWithStructuredProtoField(StructuredProtoField field,
|
||||
absl::string_view str)
|
||||
ABSL_ATTRIBUTE_NOINLINE;
|
||||
|
||||
// Returns `true` if the message is fatal or enabled debug-fatal.
|
||||
bool IsFatal() const;
|
||||
|
||||
// Records some tombstone-type data in anticipation of `Die`.
|
||||
void PrepareToDie();
|
||||
void Die();
|
||||
|
||||
void SendToLog();
|
||||
|
||||
// Checks `FLAGS_log_backtrace_at` and appends a backtrace if appropriate.
|
||||
void LogBacktraceIfNeeded();
|
||||
|
||||
// This should be the first data member so that its initializer captures errno
|
||||
// before any other initializers alter it (e.g. with calls to new) and so that
|
||||
// no other destructors run afterward an alter it (e.g. with calls to delete).
|
||||
absl::base_internal::ErrnoSaver errno_saver_;
|
||||
|
||||
// We keep the data in a separate struct so that each instance of `LogMessage`
|
||||
// uses less stack space.
|
||||
absl::Nonnull<std::unique_ptr<LogMessageData>> data_;
|
||||
};
|
||||
|
||||
// Helper class so that `AbslStringify()` can modify the LogMessage.
|
||||
class StringifySink final {
|
||||
public:
|
||||
explicit StringifySink(LogMessage& message) : message_(message) {}
|
||||
|
||||
void Append(size_t count, char ch) {
|
||||
message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(ch,
|
||||
count);
|
||||
}
|
||||
|
||||
void Append(absl::string_view v) {
|
||||
message_.CopyToEncodedBuffer<LogMessage::StringType::kNotLiteral>(v);
|
||||
}
|
||||
|
||||
// For types that implement `AbslStringify` using `absl::Format()`.
|
||||
friend void AbslFormatFlush(absl::Nonnull<StringifySink*> sink,
|
||||
absl::string_view v) {
|
||||
sink->Append(v);
|
||||
}
|
||||
|
||||
private:
|
||||
LogMessage& message_;
|
||||
};
|
||||
|
||||
// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
|
||||
template <typename T,
|
||||
typename std::enable_if<absl::HasAbslStringify<T>::value, int>::type>
|
||||
LogMessage& LogMessage::operator<<(const T& v) {
|
||||
StringifySink sink(*this);
|
||||
// Replace with public API.
|
||||
AbslStringify(sink, v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
|
||||
template <typename T,
|
||||
typename std::enable_if<!absl::HasAbslStringify<T>::value, int>::type>
|
||||
LogMessage& LogMessage::operator<<(const T& v) {
|
||||
OstreamView view(*data_);
|
||||
view.stream() << log_internal::NullGuard<T>().Guard(v);
|
||||
return *this;
|
||||
}
|
||||
|
||||
template <int SIZE>
|
||||
LogMessage& LogMessage::operator<<(const char (&buf)[SIZE]) {
|
||||
CopyToEncodedBuffer<StringType::kLiteral>(buf);
|
||||
return *this;
|
||||
}
|
||||
|
||||
// Note: the following is declared `ABSL_ATTRIBUTE_NOINLINE`
|
||||
template <int SIZE>
|
||||
LogMessage& LogMessage::operator<<(char (&buf)[SIZE]) {
|
||||
CopyToEncodedBuffer<StringType::kNotLiteral>(buf);
|
||||
return *this;
|
||||
}
|
||||
// We instantiate these specializations in the library's TU to save space in
|
||||
// other TUs. Since the template is marked `ABSL_ATTRIBUTE_NOINLINE` we will be
|
||||
// emitting a function call either way.
|
||||
// NOLINTBEGIN(runtime/int)
|
||||
// NOLINTBEGIN(google-runtime-int)
|
||||
extern template LogMessage& LogMessage::operator<<(const char& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const signed char& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const unsigned char& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const short& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const unsigned short& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const int& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const unsigned int& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const long& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const unsigned long& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const long long& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const unsigned long long& v);
|
||||
extern template LogMessage& LogMessage::operator<<(
|
||||
absl::Nullable<void*> const& v);
|
||||
extern template LogMessage& LogMessage::operator<<(
|
||||
absl::Nullable<const void*> const& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const float& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const double& v);
|
||||
extern template LogMessage& LogMessage::operator<<(const bool& v);
|
||||
// NOLINTEND(google-runtime-int)
|
||||
// NOLINTEND(runtime/int)
|
||||
|
||||
extern template void LogMessage::CopyToEncodedBuffer<
|
||||
LogMessage::StringType::kLiteral>(absl::string_view str);
|
||||
extern template void LogMessage::CopyToEncodedBuffer<
|
||||
LogMessage::StringType::kNotLiteral>(absl::string_view str);
|
||||
extern template void
|
||||
LogMessage::CopyToEncodedBuffer<LogMessage::StringType::kLiteral>(char ch,
|
||||
size_t num);
|
||||
extern template void LogMessage::CopyToEncodedBuffer<
|
||||
LogMessage::StringType::kNotLiteral>(char ch, size_t num);
|
||||
|
||||
// `LogMessageFatal` ensures the process will exit in failure after logging this
|
||||
// message.
|
||||
class LogMessageFatal final : public LogMessage {
|
||||
public:
|
||||
LogMessageFatal(absl::Nonnull<const char*> file,
|
||||
int line) ABSL_ATTRIBUTE_COLD;
|
||||
LogMessageFatal(absl::Nonnull<const char*> file, int line,
|
||||
absl::Nonnull<const char*> failure_msg) ABSL_ATTRIBUTE_COLD;
|
||||
[[noreturn]] ~LogMessageFatal();
|
||||
};
|
||||
|
||||
// `LogMessageDebugFatal` ensures the process will exit in failure after logging
|
||||
// this message. It matches LogMessageFatal but is not [[noreturn]] as it's used
|
||||
// for DLOG(FATAL) variants.
|
||||
class LogMessageDebugFatal final : public LogMessage {
|
||||
public:
|
||||
LogMessageDebugFatal(absl::Nonnull<const char*> file,
|
||||
int line) ABSL_ATTRIBUTE_COLD;
|
||||
~LogMessageDebugFatal();
|
||||
};
|
||||
|
||||
class LogMessageQuietlyDebugFatal final : public LogMessage {
|
||||
public:
|
||||
// DLOG(QFATAL) calls this instead of LogMessageQuietlyFatal to make sure the
|
||||
// destructor is not [[noreturn]] even if this is always FATAL as this is only
|
||||
// invoked when DLOG() is enabled.
|
||||
LogMessageQuietlyDebugFatal(absl::Nonnull<const char*> file,
|
||||
int line) ABSL_ATTRIBUTE_COLD;
|
||||
~LogMessageQuietlyDebugFatal();
|
||||
};
|
||||
|
||||
// Used for LOG(QFATAL) to make sure it's properly understood as [[noreturn]].
|
||||
class LogMessageQuietlyFatal final : public LogMessage {
|
||||
public:
|
||||
LogMessageQuietlyFatal(absl::Nonnull<const char*> file,
|
||||
int line) ABSL_ATTRIBUTE_COLD;
|
||||
LogMessageQuietlyFatal(absl::Nonnull<const char*> file, int line,
|
||||
absl::Nonnull<const char*> failure_msg)
|
||||
ABSL_ATTRIBUTE_COLD;
|
||||
[[noreturn]] ~LogMessageQuietlyFatal();
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
|
||||
AbslInternalOnFatalLogMessage)(const absl::LogEntry&);
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_LOG_MESSAGE_H_
|
||||
296
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_sink_set.cc
Normal file
296
TMessagesProj/jni/voip/webrtc/absl/log/internal/log_sink_set.cc
Normal file
|
|
@ -0,0 +1,296 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/log_sink_set.h"
|
||||
|
||||
#ifndef ABSL_HAVE_THREAD_LOCAL
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/call_once.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/base/no_destructor.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/cleanup/cleanup.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/config.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
|
||||
// Returns a mutable reference to a thread-local variable that should be true if
|
||||
// a globally-registered `LogSink`'s `Send()` is currently being invoked on this
|
||||
// thread.
|
||||
bool& ThreadIsLoggingStatus() {
|
||||
#ifdef ABSL_HAVE_THREAD_LOCAL
|
||||
ABSL_CONST_INIT thread_local bool thread_is_logging = false;
|
||||
return thread_is_logging;
|
||||
#else
|
||||
ABSL_CONST_INIT static pthread_key_t thread_is_logging_key;
|
||||
static const bool unused = [] {
|
||||
if (pthread_key_create(&thread_is_logging_key, [](void* data) {
|
||||
delete reinterpret_cast<bool*>(data);
|
||||
})) {
|
||||
perror("pthread_key_create failed!");
|
||||
abort();
|
||||
}
|
||||
return true;
|
||||
}();
|
||||
(void)unused; // Fixes -wunused-variable warning
|
||||
bool* thread_is_logging_ptr =
|
||||
reinterpret_cast<bool*>(pthread_getspecific(thread_is_logging_key));
|
||||
|
||||
if (ABSL_PREDICT_FALSE(!thread_is_logging_ptr)) {
|
||||
thread_is_logging_ptr = new bool{false};
|
||||
if (pthread_setspecific(thread_is_logging_key, thread_is_logging_ptr)) {
|
||||
perror("pthread_setspecific failed");
|
||||
abort();
|
||||
}
|
||||
}
|
||||
return *thread_is_logging_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
class StderrLogSink final : public LogSink {
|
||||
public:
|
||||
~StderrLogSink() override = default;
|
||||
|
||||
void Send(const absl::LogEntry& entry) override {
|
||||
if (entry.log_severity() < absl::StderrThreshold() &&
|
||||
absl::log_internal::IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
|
||||
ABSL_CONST_INIT static absl::once_flag warn_if_not_initialized;
|
||||
absl::call_once(warn_if_not_initialized, []() {
|
||||
if (absl::log_internal::IsInitialized()) return;
|
||||
const char w[] =
|
||||
"WARNING: All log messages before absl::InitializeLog() is called"
|
||||
" are written to STDERR\n";
|
||||
absl::log_internal::WriteToStderr(w, absl::LogSeverity::kWarning);
|
||||
});
|
||||
|
||||
if (!entry.stacktrace().empty()) {
|
||||
absl::log_internal::WriteToStderr(entry.stacktrace(),
|
||||
entry.log_severity());
|
||||
} else {
|
||||
// TODO(b/226937039): do this outside else condition once we avoid
|
||||
// ReprintFatalMessage
|
||||
absl::log_internal::WriteToStderr(
|
||||
entry.text_message_with_prefix_and_newline(), entry.log_severity());
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#if defined(__ANDROID__)
|
||||
class AndroidLogSink final : public LogSink {
|
||||
public:
|
||||
~AndroidLogSink() override = default;
|
||||
|
||||
void Send(const absl::LogEntry& entry) override {
|
||||
const int level = AndroidLogLevel(entry);
|
||||
const char* const tag = GetAndroidNativeTag();
|
||||
__android_log_write(level, tag,
|
||||
entry.text_message_with_prefix_and_newline_c_str());
|
||||
if (entry.log_severity() == absl::LogSeverity::kFatal)
|
||||
__android_log_write(ANDROID_LOG_FATAL, tag, "terminating.\n");
|
||||
}
|
||||
|
||||
private:
|
||||
static int AndroidLogLevel(const absl::LogEntry& entry) {
|
||||
switch (entry.log_severity()) {
|
||||
case absl::LogSeverity::kFatal:
|
||||
return ANDROID_LOG_FATAL;
|
||||
case absl::LogSeverity::kError:
|
||||
return ANDROID_LOG_ERROR;
|
||||
case absl::LogSeverity::kWarning:
|
||||
return ANDROID_LOG_WARN;
|
||||
default:
|
||||
if (entry.verbosity() >= 2) return ANDROID_LOG_VERBOSE;
|
||||
if (entry.verbosity() == 1) return ANDROID_LOG_DEBUG;
|
||||
return ANDROID_LOG_INFO;
|
||||
}
|
||||
}
|
||||
};
|
||||
#endif // !defined(__ANDROID__)
|
||||
|
||||
#if defined(_WIN32)
|
||||
class WindowsDebuggerLogSink final : public LogSink {
|
||||
public:
|
||||
~WindowsDebuggerLogSink() override = default;
|
||||
|
||||
void Send(const absl::LogEntry& entry) override {
|
||||
if (entry.log_severity() < absl::StderrThreshold() &&
|
||||
absl::log_internal::IsInitialized()) {
|
||||
return;
|
||||
}
|
||||
::OutputDebugStringA(entry.text_message_with_prefix_and_newline_c_str());
|
||||
}
|
||||
};
|
||||
#endif // !defined(_WIN32)
|
||||
|
||||
class GlobalLogSinkSet final {
|
||||
public:
|
||||
GlobalLogSinkSet() {
|
||||
#if defined(__myriad2__) || defined(__Fuchsia__)
|
||||
// myriad2 and Fuchsia do not log to stderr by default.
|
||||
#else
|
||||
static absl::NoDestructor<StderrLogSink> stderr_log_sink;
|
||||
AddLogSink(stderr_log_sink.get());
|
||||
#endif
|
||||
#ifdef __ANDROID__
|
||||
static absl::NoDestructor<AndroidLogSink> android_log_sink;
|
||||
AddLogSink(android_log_sink.get());
|
||||
#endif
|
||||
#if defined(_WIN32)
|
||||
static absl::NoDestructor<WindowsDebuggerLogSink> debugger_log_sink;
|
||||
AddLogSink(debugger_log_sink.get());
|
||||
#endif // !defined(_WIN32)
|
||||
}
|
||||
|
||||
void LogToSinks(const absl::LogEntry& entry,
|
||||
absl::Span<absl::LogSink*> extra_sinks, bool extra_sinks_only)
|
||||
ABSL_LOCKS_EXCLUDED(guard_) {
|
||||
SendToSinks(entry, extra_sinks);
|
||||
|
||||
if (!extra_sinks_only) {
|
||||
if (ThreadIsLoggingToLogSink()) {
|
||||
absl::log_internal::WriteToStderr(
|
||||
entry.text_message_with_prefix_and_newline(), entry.log_severity());
|
||||
} else {
|
||||
absl::ReaderMutexLock global_sinks_lock(&guard_);
|
||||
ThreadIsLoggingStatus() = true;
|
||||
// Ensure the "thread is logging" status is reverted upon leaving the
|
||||
// scope even in case of exceptions.
|
||||
auto status_cleanup =
|
||||
absl::MakeCleanup([] { ThreadIsLoggingStatus() = false; });
|
||||
SendToSinks(entry, absl::MakeSpan(sinks_));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void AddLogSink(absl::LogSink* sink) ABSL_LOCKS_EXCLUDED(guard_) {
|
||||
{
|
||||
absl::WriterMutexLock global_sinks_lock(&guard_);
|
||||
auto pos = std::find(sinks_.begin(), sinks_.end(), sink);
|
||||
if (pos == sinks_.end()) {
|
||||
sinks_.push_back(sink);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ABSL_INTERNAL_LOG(FATAL, "Duplicate log sinks are not supported");
|
||||
}
|
||||
|
||||
void RemoveLogSink(absl::LogSink* sink) ABSL_LOCKS_EXCLUDED(guard_) {
|
||||
{
|
||||
absl::WriterMutexLock global_sinks_lock(&guard_);
|
||||
auto pos = std::find(sinks_.begin(), sinks_.end(), sink);
|
||||
if (pos != sinks_.end()) {
|
||||
sinks_.erase(pos);
|
||||
return;
|
||||
}
|
||||
}
|
||||
ABSL_INTERNAL_LOG(FATAL, "Mismatched log sink being removed");
|
||||
}
|
||||
|
||||
void FlushLogSinks() ABSL_LOCKS_EXCLUDED(guard_) {
|
||||
if (ThreadIsLoggingToLogSink()) {
|
||||
// The thread_local condition demonstrates that we're already holding the
|
||||
// lock in order to iterate over `sinks_` for dispatch. The thread-safety
|
||||
// annotations don't know this, so we use `ABSL_NO_THREAD_SAFETY_ANALYSIS`
|
||||
guard_.AssertReaderHeld();
|
||||
FlushLogSinksLocked();
|
||||
} else {
|
||||
absl::ReaderMutexLock global_sinks_lock(&guard_);
|
||||
// In case if LogSink::Flush overload decides to log
|
||||
ThreadIsLoggingStatus() = true;
|
||||
// Ensure the "thread is logging" status is reverted upon leaving the
|
||||
// scope even in case of exceptions.
|
||||
auto status_cleanup =
|
||||
absl::MakeCleanup([] { ThreadIsLoggingStatus() = false; });
|
||||
FlushLogSinksLocked();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
void FlushLogSinksLocked() ABSL_SHARED_LOCKS_REQUIRED(guard_) {
|
||||
for (absl::LogSink* sink : sinks_) {
|
||||
sink->Flush();
|
||||
}
|
||||
}
|
||||
|
||||
// Helper routine for LogToSinks.
|
||||
static void SendToSinks(const absl::LogEntry& entry,
|
||||
absl::Span<absl::LogSink*> sinks) {
|
||||
for (absl::LogSink* sink : sinks) {
|
||||
sink->Send(entry);
|
||||
}
|
||||
}
|
||||
|
||||
using LogSinksSet = std::vector<absl::LogSink*>;
|
||||
absl::Mutex guard_;
|
||||
LogSinksSet sinks_ ABSL_GUARDED_BY(guard_);
|
||||
};
|
||||
|
||||
// Returns reference to the global LogSinks set.
|
||||
GlobalLogSinkSet& GlobalSinks() {
|
||||
static absl::NoDestructor<GlobalLogSinkSet> global_sinks;
|
||||
return *global_sinks;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
bool ThreadIsLoggingToLogSink() { return ThreadIsLoggingStatus(); }
|
||||
|
||||
void LogToSinks(const absl::LogEntry& entry,
|
||||
absl::Span<absl::LogSink*> extra_sinks, bool extra_sinks_only) {
|
||||
log_internal::GlobalSinks().LogToSinks(entry, extra_sinks, extra_sinks_only);
|
||||
}
|
||||
|
||||
void AddLogSink(absl::LogSink* sink) {
|
||||
log_internal::GlobalSinks().AddLogSink(sink);
|
||||
}
|
||||
|
||||
void RemoveLogSink(absl::LogSink* sink) {
|
||||
log_internal::GlobalSinks().RemoveLogSink(sink);
|
||||
}
|
||||
|
||||
void FlushLogSinks() { log_internal::GlobalSinks().FlushLogSinks(); }
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/log_sink_set.h
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_LOG_SINK_SET_H_
|
||||
#define ABSL_LOG_INTERNAL_LOG_SINK_SET_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// Returns true if a globally-registered `LogSink`'s `Send()` is currently
|
||||
// being invoked on this thread.
|
||||
bool ThreadIsLoggingToLogSink();
|
||||
|
||||
// This function may log to two sets of sinks:
|
||||
//
|
||||
// * If `extra_sinks_only` is true, it will dispatch only to `extra_sinks`.
|
||||
// `LogMessage::ToSinkAlso` and `LogMessage::ToSinkOnly` are used to attach
|
||||
// extra sinks to the entry.
|
||||
// * Otherwise it will also log to the global sinks set. This set is managed
|
||||
// by `absl::AddLogSink` and `absl::RemoveLogSink`.
|
||||
void LogToSinks(const absl::LogEntry& entry,
|
||||
absl::Span<absl::LogSink*> extra_sinks, bool extra_sinks_only);
|
||||
|
||||
// Implementation for operations with log sink set.
|
||||
void AddLogSink(absl::LogSink* sink);
|
||||
void RemoveLogSink(absl::LogSink* sink);
|
||||
void FlushLogSinks();
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_LOG_SINK_SET_H_
|
||||
35
TMessagesProj/jni/voip/webrtc/absl/log/internal/nullguard.cc
Normal file
35
TMessagesProj/jni/voip/webrtc/absl/log/internal/nullguard.cc
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2023 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/nullguard.h"
|
||||
|
||||
#include <array>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
ABSL_CONST_INIT ABSL_DLL const std::array<char, 7> kCharNull{
|
||||
{'(', 'n', 'u', 'l', 'l', ')', '\0'}};
|
||||
ABSL_CONST_INIT ABSL_DLL const std::array<signed char, 7> kSignedCharNull{
|
||||
{'(', 'n', 'u', 'l', 'l', ')', '\0'}};
|
||||
ABSL_CONST_INIT ABSL_DLL const std::array<unsigned char, 7> kUnsignedCharNull{
|
||||
{'(', 'n', 'u', 'l', 'l', ')', '\0'}};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
88
TMessagesProj/jni/voip/webrtc/absl/log/internal/nullguard.h
Normal file
88
TMessagesProj/jni/voip/webrtc/absl/log/internal/nullguard.h
Normal file
|
|
@ -0,0 +1,88 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/nullguard.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// NullGuard exists such that NullGuard<T>::Guard(v) returns v, unless passed a
|
||||
// nullptr_t, or a null char* or const char*, in which case it returns "(null)".
|
||||
// This allows streaming NullGuard<T>::Guard(v) to an output stream without
|
||||
// hitting undefined behavior for null values.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_NULLGUARD_H_
|
||||
#define ABSL_LOG_INTERNAL_NULLGUARD_H_
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
ABSL_CONST_INIT ABSL_DLL extern const std::array<char, 7> kCharNull;
|
||||
ABSL_CONST_INIT ABSL_DLL extern const std::array<signed char, 7>
|
||||
kSignedCharNull;
|
||||
ABSL_CONST_INIT ABSL_DLL extern const std::array<unsigned char, 7>
|
||||
kUnsignedCharNull;
|
||||
|
||||
template <typename T>
|
||||
struct NullGuard final {
|
||||
static const T& Guard(const T& v) { return v; }
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<char*> final {
|
||||
static const char* Guard(const char* v) { return v ? v : kCharNull.data(); }
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<const char*> final {
|
||||
static const char* Guard(const char* v) { return v ? v : kCharNull.data(); }
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<signed char*> final {
|
||||
static const signed char* Guard(const signed char* v) {
|
||||
return v ? v : kSignedCharNull.data();
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<const signed char*> final {
|
||||
static const signed char* Guard(const signed char* v) {
|
||||
return v ? v : kSignedCharNull.data();
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<unsigned char*> final {
|
||||
static const unsigned char* Guard(const unsigned char* v) {
|
||||
return v ? v : kUnsignedCharNull.data();
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<const unsigned char*> final {
|
||||
static const unsigned char* Guard(const unsigned char* v) {
|
||||
return v ? v : kUnsignedCharNull.data();
|
||||
}
|
||||
};
|
||||
template <>
|
||||
struct NullGuard<std::nullptr_t> final {
|
||||
static const char* Guard(const std::nullptr_t&) { return kCharNull.data(); }
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_NULLGUARD_H_
|
||||
127
TMessagesProj/jni/voip/webrtc/absl/log/internal/nullstream.h
Normal file
127
TMessagesProj/jni/voip/webrtc/absl/log/internal/nullstream.h
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/nullstream.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Classes `NullStream`, `NullStreamMaybeFatal ` and `NullStreamFatal`
|
||||
// implement a subset of the `LogMessage` API and are used instead when logging
|
||||
// of messages has been disabled.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_NULLSTREAM_H_
|
||||
#define ABSL_LOG_INTERNAL_NULLSTREAM_H_
|
||||
|
||||
#ifdef _WIN32
|
||||
#include <cstdlib>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <ios>
|
||||
#include <ostream>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// A `NullStream` implements the API of `LogMessage` (a few methods and
|
||||
// `operator<<`) but does nothing. All methods are defined inline so the
|
||||
// compiler can eliminate the whole instance and discard anything that's
|
||||
// streamed in.
|
||||
class NullStream {
|
||||
public:
|
||||
NullStream& AtLocation(absl::string_view, int) { return *this; }
|
||||
template <typename SourceLocationType>
|
||||
NullStream& AtLocation(SourceLocationType) {
|
||||
return *this;
|
||||
}
|
||||
NullStream& NoPrefix() { return *this; }
|
||||
NullStream& WithVerbosity(int) { return *this; }
|
||||
template <typename TimeType>
|
||||
NullStream& WithTimestamp(TimeType) {
|
||||
return *this;
|
||||
}
|
||||
template <typename Tid>
|
||||
NullStream& WithThreadID(Tid) {
|
||||
return *this;
|
||||
}
|
||||
template <typename LogEntryType>
|
||||
NullStream& WithMetadataFrom(const LogEntryType&) {
|
||||
return *this;
|
||||
}
|
||||
NullStream& WithPerror() { return *this; }
|
||||
template <typename LogSinkType>
|
||||
NullStream& ToSinkAlso(LogSinkType*) {
|
||||
return *this;
|
||||
}
|
||||
template <typename LogSinkType>
|
||||
NullStream& ToSinkOnly(LogSinkType*) {
|
||||
return *this;
|
||||
}
|
||||
template <typename LogSinkType>
|
||||
NullStream& OutputToSink(LogSinkType*, bool) {
|
||||
return *this;
|
||||
}
|
||||
NullStream& InternalStream() { return *this; }
|
||||
};
|
||||
template <typename T>
|
||||
inline NullStream& operator<<(NullStream& str, const T&) {
|
||||
return str;
|
||||
}
|
||||
inline NullStream& operator<<(NullStream& str,
|
||||
std::ostream& (*)(std::ostream& os)) {
|
||||
return str;
|
||||
}
|
||||
inline NullStream& operator<<(NullStream& str,
|
||||
std::ios_base& (*)(std::ios_base& os)) {
|
||||
return str;
|
||||
}
|
||||
|
||||
// `NullStreamMaybeFatal` implements the process termination semantics of
|
||||
// `LogMessage`, which is used for `DFATAL` severity and expression-defined
|
||||
// severity e.g. `LOG(LEVEL(HowBadIsIt()))`. Like `LogMessage`, it terminates
|
||||
// the process when destroyed if the passed-in severity equals `FATAL`.
|
||||
class NullStreamMaybeFatal final : public NullStream {
|
||||
public:
|
||||
explicit NullStreamMaybeFatal(absl::LogSeverity severity)
|
||||
: fatal_(severity == absl::LogSeverity::kFatal) {}
|
||||
~NullStreamMaybeFatal() {
|
||||
if (fatal_) {
|
||||
_exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool fatal_;
|
||||
};
|
||||
|
||||
// `NullStreamFatal` implements the process termination semantics of
|
||||
// `LogMessageFatal`, which means it always terminates the process. `DFATAL`
|
||||
// and expression-defined severity use `NullStreamMaybeFatal` above.
|
||||
class NullStreamFatal final : public NullStream {
|
||||
public:
|
||||
NullStreamFatal() = default;
|
||||
[[noreturn]] ~NullStreamFatal() { _exit(1); }
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_GLOBALS_H_
|
||||
217
TMessagesProj/jni/voip/webrtc/absl/log/internal/proto.cc
Normal file
217
TMessagesProj/jni/voip/webrtc/absl/log/internal/proto.cc
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
// Copyright 2020 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/proto.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
void EncodeRawVarint(uint64_t value, size_t size, absl::Span<char> *buf) {
|
||||
for (size_t s = 0; s < size; s++) {
|
||||
(*buf)[s] = static_cast<char>((value & 0x7f) | (s + 1 == size ? 0 : 0x80));
|
||||
value >>= 7;
|
||||
}
|
||||
buf->remove_prefix(size);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
|
||||
const uint64_t tag_type = MakeTagType(tag, WireType::kVarint);
|
||||
const size_t tag_type_size = VarintSize(tag_type);
|
||||
const size_t value_size = VarintSize(value);
|
||||
if (tag_type_size + value_size > buf->size()) {
|
||||
buf->remove_suffix(buf->size());
|
||||
return false;
|
||||
}
|
||||
EncodeRawVarint(tag_type, tag_type_size, buf);
|
||||
EncodeRawVarint(value, value_size, buf);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Encode64Bit(uint64_t tag, uint64_t value, absl::Span<char> *buf) {
|
||||
const uint64_t tag_type = MakeTagType(tag, WireType::k64Bit);
|
||||
const size_t tag_type_size = VarintSize(tag_type);
|
||||
if (tag_type_size + sizeof(value) > buf->size()) {
|
||||
buf->remove_suffix(buf->size());
|
||||
return false;
|
||||
}
|
||||
EncodeRawVarint(tag_type, tag_type_size, buf);
|
||||
for (size_t s = 0; s < sizeof(value); s++) {
|
||||
(*buf)[s] = static_cast<char>(value & 0xff);
|
||||
value >>= 8;
|
||||
}
|
||||
buf->remove_prefix(sizeof(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Encode32Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
|
||||
const uint64_t tag_type = MakeTagType(tag, WireType::k32Bit);
|
||||
const size_t tag_type_size = VarintSize(tag_type);
|
||||
if (tag_type_size + sizeof(value) > buf->size()) {
|
||||
buf->remove_suffix(buf->size());
|
||||
return false;
|
||||
}
|
||||
EncodeRawVarint(tag_type, tag_type_size, buf);
|
||||
for (size_t s = 0; s < sizeof(value); s++) {
|
||||
(*buf)[s] = static_cast<char>(value & 0xff);
|
||||
value >>= 8;
|
||||
}
|
||||
buf->remove_prefix(sizeof(value));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EncodeBytes(uint64_t tag, absl::Span<const char> value,
|
||||
absl::Span<char> *buf) {
|
||||
const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
|
||||
const size_t tag_type_size = VarintSize(tag_type);
|
||||
uint64_t length = value.size();
|
||||
const size_t length_size = VarintSize(length);
|
||||
if (tag_type_size + length_size + value.size() > buf->size()) {
|
||||
buf->remove_suffix(buf->size());
|
||||
return false;
|
||||
}
|
||||
EncodeRawVarint(tag_type, tag_type_size, buf);
|
||||
EncodeRawVarint(length, length_size, buf);
|
||||
memcpy(buf->data(), value.data(), value.size());
|
||||
buf->remove_prefix(value.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EncodeBytesTruncate(uint64_t tag, absl::Span<const char> value,
|
||||
absl::Span<char> *buf) {
|
||||
const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
|
||||
const size_t tag_type_size = VarintSize(tag_type);
|
||||
uint64_t length = value.size();
|
||||
const size_t length_size =
|
||||
VarintSize(std::min<uint64_t>(length, buf->size()));
|
||||
if (tag_type_size + length_size <= buf->size() &&
|
||||
tag_type_size + length_size + value.size() > buf->size()) {
|
||||
value.remove_suffix(tag_type_size + length_size + value.size() -
|
||||
buf->size());
|
||||
length = value.size();
|
||||
}
|
||||
if (tag_type_size + length_size + value.size() > buf->size()) {
|
||||
buf->remove_suffix(buf->size());
|
||||
return false;
|
||||
}
|
||||
EncodeRawVarint(tag_type, tag_type_size, buf);
|
||||
EncodeRawVarint(length, length_size, buf);
|
||||
memcpy(buf->data(), value.data(), value.size());
|
||||
buf->remove_prefix(value.size());
|
||||
return true;
|
||||
}
|
||||
|
||||
ABSL_MUST_USE_RESULT absl::Span<char> EncodeMessageStart(
|
||||
uint64_t tag, uint64_t max_size, absl::Span<char> *buf) {
|
||||
const uint64_t tag_type = MakeTagType(tag, WireType::kLengthDelimited);
|
||||
const size_t tag_type_size = VarintSize(tag_type);
|
||||
max_size = std::min<uint64_t>(max_size, buf->size());
|
||||
const size_t length_size = VarintSize(max_size);
|
||||
if (tag_type_size + length_size > buf->size()) {
|
||||
buf->remove_suffix(buf->size());
|
||||
return absl::Span<char>();
|
||||
}
|
||||
EncodeRawVarint(tag_type, tag_type_size, buf);
|
||||
const absl::Span<char> ret = buf->subspan(0, length_size);
|
||||
EncodeRawVarint(0, length_size, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
void EncodeMessageLength(absl::Span<char> msg, const absl::Span<char> *buf) {
|
||||
if (!msg.data()) return;
|
||||
assert(buf->data() >= msg.data());
|
||||
if (buf->data() < msg.data()) return;
|
||||
EncodeRawVarint(
|
||||
static_cast<uint64_t>(buf->data() - (msg.data() + msg.size())),
|
||||
msg.size(), &msg);
|
||||
}
|
||||
|
||||
namespace {
|
||||
uint64_t DecodeVarint(absl::Span<const char> *buf) {
|
||||
uint64_t value = 0;
|
||||
size_t s = 0;
|
||||
while (s < buf->size()) {
|
||||
value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]) & 0x7f)
|
||||
<< 7 * s;
|
||||
if (!((*buf)[s++] & 0x80)) break;
|
||||
}
|
||||
buf->remove_prefix(s);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint64_t Decode64Bit(absl::Span<const char> *buf) {
|
||||
uint64_t value = 0;
|
||||
size_t s = 0;
|
||||
while (s < buf->size()) {
|
||||
value |= static_cast<uint64_t>(static_cast<unsigned char>((*buf)[s]))
|
||||
<< 8 * s;
|
||||
if (++s == sizeof(value)) break;
|
||||
}
|
||||
buf->remove_prefix(s);
|
||||
return value;
|
||||
}
|
||||
|
||||
uint32_t Decode32Bit(absl::Span<const char> *buf) {
|
||||
uint32_t value = 0;
|
||||
size_t s = 0;
|
||||
while (s < buf->size()) {
|
||||
value |= static_cast<uint32_t>(static_cast<unsigned char>((*buf)[s]))
|
||||
<< 8 * s;
|
||||
if (++s == sizeof(value)) break;
|
||||
}
|
||||
buf->remove_prefix(s);
|
||||
return value;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool ProtoField::DecodeFrom(absl::Span<const char> *data) {
|
||||
if (data->empty()) return false;
|
||||
const uint64_t tag_type = DecodeVarint(data);
|
||||
tag_ = tag_type >> 3;
|
||||
type_ = static_cast<WireType>(tag_type & 0x07);
|
||||
switch (type_) {
|
||||
case WireType::kVarint:
|
||||
value_ = DecodeVarint(data);
|
||||
break;
|
||||
case WireType::k64Bit:
|
||||
value_ = Decode64Bit(data);
|
||||
break;
|
||||
case WireType::kLengthDelimited: {
|
||||
value_ = DecodeVarint(data);
|
||||
data_ = data->subspan(
|
||||
0, static_cast<size_t>(std::min<uint64_t>(value_, data->size())));
|
||||
data->remove_prefix(data_.size());
|
||||
break;
|
||||
}
|
||||
case WireType::k32Bit:
|
||||
value_ = Decode32Bit(data);
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
298
TMessagesProj/jni/voip/webrtc/absl/log/internal/proto.h
Normal file
298
TMessagesProj/jni/voip/webrtc/absl/log/internal/proto.h
Normal file
|
|
@ -0,0 +1,298 @@
|
|||
// Copyright 2020 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: internal/proto.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// Declares functions for serializing and deserializing data to and from memory
|
||||
// buffers in protocol buffer wire format. This library takes no steps to
|
||||
// ensure that the encoded data matches with any message specification.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_PROTO_H_
|
||||
#define ABSL_LOG_INTERNAL_PROTO_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <limits>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/casts.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// absl::Span<char> represents a view into the available space in a mutable
|
||||
// buffer during encoding. Encoding functions shrink the span as they go so
|
||||
// that the same view can be passed to a series of Encode functions. If the
|
||||
// data do not fit, nothing is encoded, the view is set to size zero (so that
|
||||
// all subsequent encode calls fail), and false is returned. Otherwise true is
|
||||
// returned.
|
||||
|
||||
// In particular, attempting to encode a series of data into an insufficient
|
||||
// buffer has consistent and efficient behavior without any caller-side error
|
||||
// checking. Individual values will be encoded in their entirety or not at all
|
||||
// (unless one of the `Truncate` functions is used). Once a value is omitted
|
||||
// because it does not fit, no subsequent values will be encoded to preserve
|
||||
// ordering; the decoded sequence will be a prefix of the original sequence.
|
||||
|
||||
// There are two ways to encode a message-typed field:
|
||||
//
|
||||
// * Construct its contents in a separate buffer and use `EncodeBytes` to copy
|
||||
// it into the primary buffer with type, tag, and length.
|
||||
// * Use `EncodeMessageStart` to write type and tag fields and reserve space for
|
||||
// the length field, then encode the contents directly into the buffer, then
|
||||
// use `EncodeMessageLength` to write the actual length into the reserved
|
||||
// bytes. This works fine if the actual length takes fewer bytes to encode
|
||||
// than were reserved, although you don't get your extra bytes back.
|
||||
// This approach will always produce a valid encoding, but your protocol may
|
||||
// require that the whole message field by omitted if the buffer is too small
|
||||
// to contain all desired subfields. In this case, operate on a copy of the
|
||||
// buffer view and assign back only if everything fit, i.e. if the last
|
||||
// `Encode` call returned true.
|
||||
|
||||
// Encodes the specified integer as a varint field and returns true if it fits.
|
||||
// Used for int32_t, int64_t, uint32_t, uint64_t, bool, and enum field types.
|
||||
// Consumes up to kMaxVarintSize * 2 bytes (20).
|
||||
bool EncodeVarint(uint64_t tag, uint64_t value, absl::Span<char> *buf);
|
||||
inline bool EncodeVarint(uint64_t tag, int64_t value, absl::Span<char> *buf) {
|
||||
return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
inline bool EncodeVarint(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
|
||||
return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
inline bool EncodeVarint(uint64_t tag, int32_t value, absl::Span<char> *buf) {
|
||||
return EncodeVarint(tag, static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
|
||||
// Encodes the specified integer as a varint field using ZigZag encoding and
|
||||
// returns true if it fits.
|
||||
// Used for sint32 and sint64 field types.
|
||||
// Consumes up to kMaxVarintSize * 2 bytes (20).
|
||||
inline bool EncodeVarintZigZag(uint64_t tag, int64_t value,
|
||||
absl::Span<char> *buf) {
|
||||
if (value < 0)
|
||||
return EncodeVarint(tag, 2 * static_cast<uint64_t>(-(value + 1)) + 1, buf);
|
||||
return EncodeVarint(tag, 2 * static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
|
||||
// Encodes the specified integer as a 64-bit field and returns true if it fits.
|
||||
// Used for fixed64 and sfixed64 field types.
|
||||
// Consumes up to kMaxVarintSize + 8 bytes (18).
|
||||
bool Encode64Bit(uint64_t tag, uint64_t value, absl::Span<char> *buf);
|
||||
inline bool Encode64Bit(uint64_t tag, int64_t value, absl::Span<char> *buf) {
|
||||
return Encode64Bit(tag, static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
inline bool Encode64Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf) {
|
||||
return Encode64Bit(tag, static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
inline bool Encode64Bit(uint64_t tag, int32_t value, absl::Span<char> *buf) {
|
||||
return Encode64Bit(tag, static_cast<uint64_t>(value), buf);
|
||||
}
|
||||
|
||||
// Encodes the specified double as a 64-bit field and returns true if it fits.
|
||||
// Used for double field type.
|
||||
// Consumes up to kMaxVarintSize + 8 bytes (18).
|
||||
inline bool EncodeDouble(uint64_t tag, double value, absl::Span<char> *buf) {
|
||||
return Encode64Bit(tag, absl::bit_cast<uint64_t>(value), buf);
|
||||
}
|
||||
|
||||
// Encodes the specified integer as a 32-bit field and returns true if it fits.
|
||||
// Used for fixed32 and sfixed32 field types.
|
||||
// Consumes up to kMaxVarintSize + 4 bytes (14).
|
||||
bool Encode32Bit(uint64_t tag, uint32_t value, absl::Span<char> *buf);
|
||||
inline bool Encode32Bit(uint64_t tag, int32_t value, absl::Span<char> *buf) {
|
||||
return Encode32Bit(tag, static_cast<uint32_t>(value), buf);
|
||||
}
|
||||
|
||||
// Encodes the specified float as a 32-bit field and returns true if it fits.
|
||||
// Used for float field type.
|
||||
// Consumes up to kMaxVarintSize + 4 bytes (14).
|
||||
inline bool EncodeFloat(uint64_t tag, float value, absl::Span<char> *buf) {
|
||||
return Encode32Bit(tag, absl::bit_cast<uint32_t>(value), buf);
|
||||
}
|
||||
|
||||
// Encodes the specified bytes as a length-delimited field and returns true if
|
||||
// they fit.
|
||||
// Used for string, bytes, message, and packed-repeated field type.
|
||||
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
|
||||
bool EncodeBytes(uint64_t tag, absl::Span<const char> value,
|
||||
absl::Span<char> *buf);
|
||||
|
||||
// Encodes as many of the specified bytes as will fit as a length-delimited
|
||||
// field and returns true as long as the field header (`tag_type` and `length`)
|
||||
// fits.
|
||||
// Used for string, bytes, message, and packed-repeated field type.
|
||||
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
|
||||
bool EncodeBytesTruncate(uint64_t tag, absl::Span<const char> value,
|
||||
absl::Span<char> *buf);
|
||||
|
||||
// Encodes the specified string as a length-delimited field and returns true if
|
||||
// it fits.
|
||||
// Used for string, bytes, message, and packed-repeated field type.
|
||||
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
|
||||
inline bool EncodeString(uint64_t tag, absl::string_view value,
|
||||
absl::Span<char> *buf) {
|
||||
return EncodeBytes(tag, value, buf);
|
||||
}
|
||||
|
||||
// Encodes as much of the specified string as will fit as a length-delimited
|
||||
// field and returns true as long as the field header (`tag_type` and `length`)
|
||||
// fits.
|
||||
// Used for string, bytes, message, and packed-repeated field type.
|
||||
// Consumes up to kMaxVarintSize * 2 + value.size() bytes (20 + value.size()).
|
||||
inline bool EncodeStringTruncate(uint64_t tag, absl::string_view value,
|
||||
absl::Span<char> *buf) {
|
||||
return EncodeBytesTruncate(tag, value, buf);
|
||||
}
|
||||
|
||||
// Encodes the header for a length-delimited field containing up to `max_size`
|
||||
// bytes or the number remaining in the buffer, whichever is less. If the
|
||||
// header fits, a non-nullptr `Span` is returned; this must be passed to
|
||||
// `EncodeMessageLength` after all contents are encoded to finalize the length
|
||||
// field. If the header does not fit, a nullptr `Span` is returned which is
|
||||
// safe to pass to `EncodeMessageLength` but need not be.
|
||||
// Used for string, bytes, message, and packed-repeated field type.
|
||||
// Consumes up to kMaxVarintSize * 2 bytes (20).
|
||||
ABSL_MUST_USE_RESULT absl::Span<char> EncodeMessageStart(uint64_t tag,
|
||||
uint64_t max_size,
|
||||
absl::Span<char> *buf);
|
||||
|
||||
// Finalizes the length field in `msg` so that it encompasses all data encoded
|
||||
// since the call to `EncodeMessageStart` which returned `msg`. Does nothing if
|
||||
// `msg` is a `nullptr` `Span`.
|
||||
void EncodeMessageLength(absl::Span<char> msg, const absl::Span<char> *buf);
|
||||
|
||||
enum class WireType : uint64_t {
|
||||
kVarint = 0,
|
||||
k64Bit = 1,
|
||||
kLengthDelimited = 2,
|
||||
k32Bit = 5,
|
||||
};
|
||||
|
||||
constexpr size_t VarintSize(uint64_t value) {
|
||||
return value < 128 ? 1 : 1 + VarintSize(value >> 7);
|
||||
}
|
||||
constexpr size_t MinVarintSize() {
|
||||
return VarintSize((std::numeric_limits<uint64_t>::min)());
|
||||
}
|
||||
constexpr size_t MaxVarintSize() {
|
||||
return VarintSize((std::numeric_limits<uint64_t>::max)());
|
||||
}
|
||||
|
||||
constexpr uint64_t MaxVarintForSize(size_t size) {
|
||||
return size >= 10 ? (std::numeric_limits<uint64_t>::max)()
|
||||
: (static_cast<uint64_t>(1) << size * 7) - 1;
|
||||
}
|
||||
constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
|
||||
return tag << 3 | static_cast<uint64_t>(type);
|
||||
}
|
||||
|
||||
// `BufferSizeFor` returns a number of bytes guaranteed to be sufficient to
|
||||
// store encoded fields as `(tag, WireType)`, regardless of data values. This
|
||||
// only makes sense for `WireType::kLengthDelimited` if you add in the length of
|
||||
// the contents yourself, e.g. for string and bytes fields by adding the lengths
|
||||
// of any encoded strings to the return value or for submessage fields by
|
||||
// enumerating the fields you may encode into their contents.
|
||||
constexpr size_t BufferSizeFor(uint64_t tag, WireType type) {
|
||||
size_t buffer_size = VarintSize(MakeTagType(tag, type));
|
||||
switch (type) {
|
||||
case WireType::kVarint:
|
||||
buffer_size += MaxVarintSize();
|
||||
break;
|
||||
case WireType::k64Bit:
|
||||
buffer_size += size_t{8};
|
||||
break;
|
||||
case WireType::kLengthDelimited:
|
||||
buffer_size += MaxVarintSize();
|
||||
break;
|
||||
case WireType::k32Bit:
|
||||
buffer_size += size_t{4};
|
||||
break;
|
||||
}
|
||||
return buffer_size;
|
||||
}
|
||||
|
||||
// absl::Span<const char> represents a view into the un-processed space in a
|
||||
// buffer during decoding. Decoding functions shrink the span as they go so
|
||||
// that the same view can be decoded iteratively until all data are processed.
|
||||
// In general, if the buffer is exhausted but additional bytes are expected by
|
||||
// the decoder, it will return values as if the additional bytes were zeros.
|
||||
// Length-delimited fields are an exception - if the encoded length field
|
||||
// indicates more data bytes than are available in the buffer, the `bytes_value`
|
||||
// and `string_value` accessors will return truncated views.
|
||||
|
||||
class ProtoField final {
|
||||
public:
|
||||
// Consumes bytes from `data` and returns true if there were any bytes to
|
||||
// decode.
|
||||
bool DecodeFrom(absl::Span<const char> *data);
|
||||
uint64_t tag() const { return tag_; }
|
||||
WireType type() const { return type_; }
|
||||
|
||||
// These value accessors will return nonsense if the data were not encoded in
|
||||
// the corresponding wiretype from the corresponding C++ (or other language)
|
||||
// type.
|
||||
|
||||
double double_value() const { return absl::bit_cast<double>(value_); }
|
||||
float float_value() const {
|
||||
return absl::bit_cast<float>(static_cast<uint32_t>(value_));
|
||||
}
|
||||
int32_t int32_value() const { return static_cast<int32_t>(value_); }
|
||||
int64_t int64_value() const { return static_cast<int64_t>(value_); }
|
||||
int32_t sint32_value() const {
|
||||
if (value_ % 2) return static_cast<int32_t>(0 - ((value_ - 1) / 2) - 1);
|
||||
return static_cast<int32_t>(value_ / 2);
|
||||
}
|
||||
int64_t sint64_value() const {
|
||||
if (value_ % 2) return 0 - ((value_ - 1) / 2) - 1;
|
||||
return value_ / 2;
|
||||
}
|
||||
uint32_t uint32_value() const { return static_cast<uint32_t>(value_); }
|
||||
uint64_t uint64_value() const { return value_; }
|
||||
bool bool_value() const { return value_ != 0; }
|
||||
// To decode an enum, call int32_value() and cast to the appropriate type.
|
||||
// Note that the official C++ proto compiler treats enum fields with values
|
||||
// that do not correspond to a defined enumerator as unknown fields.
|
||||
|
||||
// To decode fields within a submessage field, call
|
||||
// `DecodeNextField(field.BytesValue())`.
|
||||
absl::Span<const char> bytes_value() const { return data_; }
|
||||
absl::string_view string_value() const {
|
||||
const auto data = bytes_value();
|
||||
return absl::string_view(data.data(), data.size());
|
||||
}
|
||||
// Returns the encoded length of a length-delimited field. This equals
|
||||
// `bytes_value().size()` except when the latter has been truncated due to
|
||||
// buffer underrun.
|
||||
uint64_t encoded_length() const { return value_; }
|
||||
|
||||
private:
|
||||
uint64_t tag_;
|
||||
WireType type_;
|
||||
// For `kTypeVarint`, `kType64Bit`, and `kType32Bit`, holds the decoded value.
|
||||
// For `kTypeLengthDelimited`, holds the decoded length.
|
||||
uint64_t value_;
|
||||
absl::Span<const char> data_;
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_PROTO_H_
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/log.h"
|
||||
|
||||
namespace {
|
||||
using ::testing::AllOf;
|
||||
using ::testing::HasSubstr;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
MATCHER_P2(HasSubstrTimes, substr, expected_count, "") {
|
||||
int count = 0;
|
||||
std::string::size_type pos = 0;
|
||||
std::string needle(substr);
|
||||
while ((pos = arg.find(needle, pos)) != std::string::npos) {
|
||||
++count;
|
||||
pos += needle.size();
|
||||
}
|
||||
|
||||
return count == expected_count;
|
||||
}
|
||||
|
||||
TEST(StderrLogSinkDeathTest, InfoMessagesInStderr) {
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
|
||||
LOG(INFO) << "INFO message";
|
||||
exit(1);
|
||||
},
|
||||
"INFO message");
|
||||
}
|
||||
|
||||
TEST(StderrLogSinkDeathTest, WarningMessagesInStderr) {
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
|
||||
LOG(WARNING) << "WARNING message";
|
||||
exit(1);
|
||||
},
|
||||
"WARNING message");
|
||||
}
|
||||
|
||||
TEST(StderrLogSinkDeathTest, ErrorMessagesInStderr) {
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
|
||||
LOG(ERROR) << "ERROR message";
|
||||
exit(1);
|
||||
},
|
||||
"ERROR message");
|
||||
}
|
||||
|
||||
TEST(StderrLogSinkDeathTest, FatalMessagesInStderr) {
|
||||
char message[] = "FATAL message";
|
||||
char stacktrace[] = "*** Check failure stack trace: ***";
|
||||
|
||||
int expected_count = 1;
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
|
||||
LOG(FATAL) << message;
|
||||
},
|
||||
AllOf(HasSubstrTimes(message, expected_count), HasSubstr(stacktrace)));
|
||||
}
|
||||
|
||||
TEST(StderrLogSinkDeathTest, SecondaryFatalMessagesInStderr) {
|
||||
auto MessageGen = []() -> std::string {
|
||||
LOG(FATAL) << "Internal failure";
|
||||
return "External failure";
|
||||
};
|
||||
|
||||
EXPECT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfo);
|
||||
LOG(FATAL) << MessageGen();
|
||||
},
|
||||
"Internal failure");
|
||||
}
|
||||
|
||||
} // namespace
|
||||
97
TMessagesProj/jni/voip/webrtc/absl/log/internal/strip.h
Normal file
97
TMessagesProj/jni/voip/webrtc/absl/log/internal/strip.h
Normal file
|
|
@ -0,0 +1,97 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/strip.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_STRIP_H_
|
||||
#define ABSL_LOG_INTERNAL_STRIP_H_
|
||||
|
||||
#include "absl/base/attributes.h" // IWYU pragma: keep
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/log_message.h"
|
||||
#include "absl/log/internal/nullstream.h"
|
||||
|
||||
// `ABSL_LOGGING_INTERNAL_LOG_*` evaluates to a temporary `LogMessage` object or
|
||||
// to a related object with a compatible API but different behavior. This set
|
||||
// of defines comes in three flavors: vanilla, plus two variants that strip some
|
||||
// logging in subtly different ways for subtly different reasons (see below).
|
||||
#if defined(STRIP_LOG) && STRIP_LOG
|
||||
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_INFO ::absl::log_internal::NullStream()
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_WARNING ::absl::log_internal::NullStream()
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_ERROR ::absl::log_internal::NullStream()
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_FATAL ::absl::log_internal::NullStreamFatal()
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_QFATAL ::absl::log_internal::NullStreamFatal()
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_DFATAL \
|
||||
::absl::log_internal::NullStreamMaybeFatal(::absl::kLogDebugFatal)
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_LEVEL(severity) \
|
||||
::absl::log_internal::NullStreamMaybeFatal(absl_log_internal_severity)
|
||||
|
||||
// Fatal `DLOG`s expand a little differently to avoid being `[[noreturn]]`.
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_FATAL \
|
||||
::absl::log_internal::NullStreamMaybeFatal(::absl::LogSeverity::kFatal)
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_QFATAL \
|
||||
::absl::log_internal::NullStreamMaybeFatal(::absl::LogSeverity::kFatal)
|
||||
|
||||
#define ABSL_LOG_INTERNAL_CHECK(failure_message) ABSL_LOGGING_INTERNAL_LOG_FATAL
|
||||
#define ABSL_LOG_INTERNAL_QCHECK(failure_message) \
|
||||
ABSL_LOGGING_INTERNAL_LOG_QFATAL
|
||||
|
||||
#else // !defined(STRIP_LOG) || !STRIP_LOG
|
||||
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_INFO \
|
||||
::absl::log_internal::LogMessage( \
|
||||
__FILE__, __LINE__, ::absl::log_internal::LogMessage::InfoTag{})
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_WARNING \
|
||||
::absl::log_internal::LogMessage( \
|
||||
__FILE__, __LINE__, ::absl::log_internal::LogMessage::WarningTag{})
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_ERROR \
|
||||
::absl::log_internal::LogMessage( \
|
||||
__FILE__, __LINE__, ::absl::log_internal::LogMessage::ErrorTag{})
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_FATAL \
|
||||
::absl::log_internal::LogMessageFatal(__FILE__, __LINE__)
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_QFATAL \
|
||||
::absl::log_internal::LogMessageQuietlyFatal(__FILE__, __LINE__)
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_DFATAL \
|
||||
::absl::log_internal::LogMessage(__FILE__, __LINE__, ::absl::kLogDebugFatal)
|
||||
#define ABSL_LOGGING_INTERNAL_LOG_LEVEL(severity) \
|
||||
::absl::log_internal::LogMessage(__FILE__, __LINE__, \
|
||||
absl_log_internal_severity)
|
||||
|
||||
// Fatal `DLOG`s expand a little differently to avoid being `[[noreturn]]`.
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_FATAL \
|
||||
::absl::log_internal::LogMessageDebugFatal(__FILE__, __LINE__)
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_QFATAL \
|
||||
::absl::log_internal::LogMessageQuietlyDebugFatal(__FILE__, __LINE__)
|
||||
|
||||
// These special cases dispatch to special-case constructors that allow us to
|
||||
// avoid an extra function call and shrink non-LTO binaries by a percent or so.
|
||||
#define ABSL_LOG_INTERNAL_CHECK(failure_message) \
|
||||
::absl::log_internal::LogMessageFatal(__FILE__, __LINE__, failure_message)
|
||||
#define ABSL_LOG_INTERNAL_QCHECK(failure_message) \
|
||||
::absl::log_internal::LogMessageQuietlyFatal(__FILE__, __LINE__, \
|
||||
failure_message)
|
||||
#endif // !defined(STRIP_LOG) || !STRIP_LOG
|
||||
|
||||
// This part of a non-fatal `DLOG`s expands the same as `LOG`.
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_INFO ABSL_LOGGING_INTERNAL_LOG_INFO
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_WARNING ABSL_LOGGING_INTERNAL_LOG_WARNING
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_ERROR ABSL_LOGGING_INTERNAL_LOG_ERROR
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_DFATAL ABSL_LOGGING_INTERNAL_LOG_DFATAL
|
||||
#define ABSL_LOGGING_INTERNAL_DLOG_LEVEL ABSL_LOGGING_INTERNAL_LOG_LEVEL
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_STRIP_H_
|
||||
164
TMessagesProj/jni/voip/webrtc/absl/log/internal/structured.h
Normal file
164
TMessagesProj/jni/voip/webrtc/absl/log/internal/structured.h
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/structured.h
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_STRUCTURED_H_
|
||||
#define ABSL_LOG_INTERNAL_STRUCTURED_H_
|
||||
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/functional/any_invocable.h"
|
||||
#include "absl/log/internal/log_message.h"
|
||||
#include "absl/log/internal/structured_proto.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
class ABSL_MUST_USE_RESULT AsLiteralImpl final {
|
||||
public:
|
||||
explicit AsLiteralImpl(absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND)
|
||||
: str_(str) {}
|
||||
AsLiteralImpl(const AsLiteralImpl&) = default;
|
||||
AsLiteralImpl& operator=(const AsLiteralImpl&) = default;
|
||||
|
||||
private:
|
||||
absl::string_view str_;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,
|
||||
AsLiteralImpl&& as_literal) {
|
||||
return os << as_literal.str_;
|
||||
}
|
||||
void AddToMessage(log_internal::LogMessage& m) {
|
||||
m.CopyToEncodedBuffer<log_internal::LogMessage::StringType::kLiteral>(str_);
|
||||
}
|
||||
friend log_internal::LogMessage& operator<<(log_internal::LogMessage& m,
|
||||
AsLiteralImpl as_literal) {
|
||||
as_literal.AddToMessage(m);
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
enum class StructuredStringType {
|
||||
kLiteral,
|
||||
kNotLiteral,
|
||||
};
|
||||
|
||||
// Structured log data for a string and associated structured proto field,
|
||||
// both of which must outlive this object.
|
||||
template <StructuredStringType str_type>
|
||||
class ABSL_MUST_USE_RESULT AsStructuredStringTypeImpl final {
|
||||
public:
|
||||
constexpr AsStructuredStringTypeImpl(
|
||||
absl::string_view str ABSL_ATTRIBUTE_LIFETIME_BOUND,
|
||||
StructuredProtoField field ABSL_ATTRIBUTE_LIFETIME_BOUND)
|
||||
: str_(str), field_(field) {}
|
||||
|
||||
private:
|
||||
absl::string_view str_;
|
||||
StructuredProtoField field_;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,
|
||||
const AsStructuredStringTypeImpl& impl) {
|
||||
return os << impl.str_;
|
||||
}
|
||||
void AddToMessage(LogMessage& m) const {
|
||||
if (str_type == StructuredStringType::kLiteral) {
|
||||
return m.CopyToEncodedBufferWithStructuredProtoField<
|
||||
log_internal::LogMessage::StringType::kLiteral>(field_, str_);
|
||||
} else {
|
||||
return m.CopyToEncodedBufferWithStructuredProtoField<
|
||||
log_internal::LogMessage::StringType::kNotLiteral>(field_, str_);
|
||||
}
|
||||
}
|
||||
friend LogMessage& operator<<(LogMessage& m,
|
||||
const AsStructuredStringTypeImpl& impl) {
|
||||
impl.AddToMessage(m);
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
using AsStructuredLiteralImpl =
|
||||
AsStructuredStringTypeImpl<StructuredStringType::kLiteral>;
|
||||
using AsStructuredNotLiteralImpl =
|
||||
AsStructuredStringTypeImpl<StructuredStringType::kNotLiteral>;
|
||||
|
||||
// Structured log data for a stringifyable type T and associated structured
|
||||
// proto field, both of which must outlive this object.
|
||||
template <typename T>
|
||||
class ABSL_MUST_USE_RESULT AsStructuredValueImpl final {
|
||||
public:
|
||||
using ValueFormatter = absl::AnyInvocable<std::string(T) const>;
|
||||
|
||||
constexpr AsStructuredValueImpl(
|
||||
T value ABSL_ATTRIBUTE_LIFETIME_BOUND,
|
||||
StructuredProtoField field ABSL_ATTRIBUTE_LIFETIME_BOUND,
|
||||
ValueFormatter value_formatter =
|
||||
[](T value) { return absl::StrCat(value); })
|
||||
: value_(value),
|
||||
field_(field),
|
||||
value_formatter_(std::move(value_formatter)) {}
|
||||
|
||||
private:
|
||||
T value_;
|
||||
StructuredProtoField field_;
|
||||
ValueFormatter value_formatter_;
|
||||
|
||||
friend std::ostream& operator<<(std::ostream& os,
|
||||
const AsStructuredValueImpl& impl) {
|
||||
return os << impl.value_formatter_(impl.value_);
|
||||
}
|
||||
void AddToMessage(LogMessage& m) const {
|
||||
m.CopyToEncodedBufferWithStructuredProtoField<
|
||||
log_internal::LogMessage::StringType::kNotLiteral>(
|
||||
field_, value_formatter_(value_));
|
||||
}
|
||||
friend LogMessage& operator<<(LogMessage& m,
|
||||
const AsStructuredValueImpl& impl) {
|
||||
impl.AddToMessage(m);
|
||||
return m;
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
|
||||
|
||||
// Template deduction guide so `AsStructuredValueImpl(42, data)` works
|
||||
// without specifying the template type.
|
||||
template <typename T>
|
||||
AsStructuredValueImpl(T value, StructuredProtoField field)
|
||||
-> AsStructuredValueImpl<T>;
|
||||
|
||||
// Template deduction guide so `AsStructuredValueImpl(42, data, formatter)`
|
||||
// works without specifying the template type.
|
||||
template <typename T>
|
||||
AsStructuredValueImpl(
|
||||
T value, StructuredProtoField field,
|
||||
typename AsStructuredValueImpl<T>::ValueFormatter value_formatter)
|
||||
-> AsStructuredValueImpl<T>;
|
||||
|
||||
#endif // ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_STRUCTURED_H_
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
//
|
||||
// Copyright 2024 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/structured_proto.h"
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/proto.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "absl/types/variant.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
namespace {
|
||||
|
||||
// Handles protobuf-encoding a type contained inside
|
||||
// `StructuredProtoField::Varint`.
|
||||
struct VarintEncoderVisitor final {
|
||||
template <typename T>
|
||||
bool operator()(T value) const {
|
||||
return EncodeVarint(field_number, value, &buf);
|
||||
}
|
||||
|
||||
uint64_t field_number;
|
||||
absl::Span<char>& buf;
|
||||
};
|
||||
|
||||
// Handles protobuf-encoding a type contained inside
|
||||
// `StructuredProtoField::I64`.
|
||||
struct I64EncoderVisitor final {
|
||||
bool operator()(uint64_t value) const {
|
||||
return Encode64Bit(field_number, value, &buf);
|
||||
}
|
||||
|
||||
bool operator()(int64_t value) const {
|
||||
return Encode64Bit(field_number, value, &buf);
|
||||
}
|
||||
|
||||
bool operator()(double value) const {
|
||||
return EncodeDouble(field_number, value, &buf);
|
||||
}
|
||||
|
||||
uint64_t field_number;
|
||||
absl::Span<char>& buf;
|
||||
};
|
||||
|
||||
// Handles protobuf-encoding a type contained inside
|
||||
// `StructuredProtoField::I32`.
|
||||
struct I32EncoderVisitor final {
|
||||
bool operator()(uint32_t value) const {
|
||||
return Encode32Bit(field_number, value, &buf);
|
||||
}
|
||||
|
||||
bool operator()(int32_t value) const {
|
||||
return Encode32Bit(field_number, value, &buf);
|
||||
}
|
||||
|
||||
bool operator()(float value) const {
|
||||
return EncodeFloat(field_number, value, &buf);
|
||||
}
|
||||
|
||||
uint64_t field_number;
|
||||
absl::Span<char>& buf;
|
||||
};
|
||||
|
||||
// Handles protobuf-encoding a type contained inside `StructuredProtoField`.
|
||||
struct EncoderVisitor final {
|
||||
bool operator()(StructuredProtoField::Varint varint) {
|
||||
return absl::visit(VarintEncoderVisitor{field_number, buf}, varint);
|
||||
}
|
||||
|
||||
bool operator()(StructuredProtoField::I64 i64) {
|
||||
return absl::visit(I64EncoderVisitor{field_number, buf}, i64);
|
||||
}
|
||||
|
||||
bool operator()(StructuredProtoField::LengthDelimited length_delimited) {
|
||||
// No need for a visitor, since `StructuredProtoField::LengthDelimited` is
|
||||
// just `absl::Span<const char>`.
|
||||
return EncodeBytes(field_number, length_delimited, &buf);
|
||||
}
|
||||
|
||||
bool operator()(StructuredProtoField::I32 i32) {
|
||||
return absl::visit(I32EncoderVisitor{field_number, buf}, i32);
|
||||
}
|
||||
|
||||
uint64_t field_number;
|
||||
absl::Span<char>& buf;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
bool EncodeStructuredProtoField(StructuredProtoField field,
|
||||
absl::Span<char>& buf) {
|
||||
return absl::visit(EncoderVisitor{field.field_number, buf}, field.value);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
// Copyright 2024 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/structured_proto.h
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
|
||||
#define ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/proto.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "absl/types/variant.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// Sum type holding a single valid protobuf field suitable for encoding.
|
||||
struct StructuredProtoField final {
|
||||
// Numeric type encoded with varint encoding:
|
||||
// https://protobuf.dev/programming-guides/encoding/#varints
|
||||
using Varint = absl::variant<uint64_t, int64_t, uint32_t, int32_t, bool>;
|
||||
|
||||
// Fixed-length 64-bit integer encoding:
|
||||
// https://protobuf.dev/programming-guides/encoding/#non-varints
|
||||
using I64 = absl::variant<uint64_t, int64_t, double>;
|
||||
|
||||
// Length-delimited record type (string, sub-message):
|
||||
// https://protobuf.dev/programming-guides/encoding/#length-types
|
||||
using LengthDelimited = absl::Span<const char>;
|
||||
|
||||
// Fixed-length 32-bit integer encoding:
|
||||
// https://protobuf.dev/programming-guides/encoding/#non-varints
|
||||
using I32 = absl::variant<uint32_t, int32_t, float>;
|
||||
|
||||
// Valid record type:
|
||||
// https://protobuf.dev/programming-guides/encoding/#structure
|
||||
using Value = absl::variant<Varint, I64, LengthDelimited, I32>;
|
||||
|
||||
// Field number for the protobuf value.
|
||||
uint64_t field_number;
|
||||
|
||||
// Value to encode.
|
||||
Value value;
|
||||
};
|
||||
|
||||
// Estimates the number of bytes needed to encode `field` using
|
||||
// protobuf encoding.
|
||||
//
|
||||
// The returned value might be larger than the actual number of bytes needed.
|
||||
inline size_t BufferSizeForStructuredProtoField(StructuredProtoField field) {
|
||||
// Visitor to estimate the number of bytes of one of the types contained
|
||||
// inside `StructuredProtoField`.
|
||||
struct BufferSizeVisitor final {
|
||||
size_t operator()(StructuredProtoField::Varint /*unused*/) {
|
||||
return BufferSizeFor(field_number, WireType::kVarint);
|
||||
}
|
||||
|
||||
size_t operator()(StructuredProtoField::I64 /*unused*/) {
|
||||
return BufferSizeFor(field_number, WireType::k64Bit);
|
||||
}
|
||||
|
||||
size_t operator()(StructuredProtoField::LengthDelimited length_delimited) {
|
||||
return BufferSizeFor(field_number, WireType::kLengthDelimited) +
|
||||
length_delimited.size();
|
||||
}
|
||||
|
||||
size_t operator()(StructuredProtoField::I32 /*unused*/) {
|
||||
return BufferSizeFor(field_number, WireType::k32Bit);
|
||||
}
|
||||
|
||||
uint64_t field_number;
|
||||
};
|
||||
|
||||
return absl::visit(BufferSizeVisitor{field.field_number}, field.value);
|
||||
}
|
||||
|
||||
// Encodes `field` into `buf` using protobuf encoding.
|
||||
//
|
||||
// On success, returns `true` and advances `buf` to the end of
|
||||
// the bytes consumed.
|
||||
//
|
||||
// On failure (if `buf` was too small), returns `false`.
|
||||
bool EncodeStructuredProtoField(StructuredProtoField field,
|
||||
absl::Span<char>& buf);
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_STRUCTURED_PROTO_H_
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
//
|
||||
// Copyright 2024 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/structured_proto.h"
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/span.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
|
||||
using ::testing::TestWithParam;
|
||||
|
||||
struct StructuredProtoTestCase {
|
||||
std::string test_name;
|
||||
StructuredProtoField field;
|
||||
std::vector<char> expected_encoded_field;
|
||||
};
|
||||
|
||||
using StructuredProtoTest = TestWithParam<StructuredProtoTestCase>;
|
||||
|
||||
TEST_P(StructuredProtoTest, Encoding) {
|
||||
const StructuredProtoTestCase& test_case = GetParam();
|
||||
|
||||
// Greater than or equal to since BufferSizeForStructuredProtoField() is just
|
||||
// an estimate of the data size and not an exact measurement.
|
||||
ASSERT_GE(BufferSizeForStructuredProtoField(test_case.field),
|
||||
test_case.expected_encoded_field.size());
|
||||
|
||||
std::vector<char> buf;
|
||||
buf.resize(1024);
|
||||
|
||||
absl::Span<char> buf_span(buf);
|
||||
EXPECT_TRUE(EncodeStructuredProtoField(test_case.field, buf_span));
|
||||
size_t encoded_field_size = buf.size() - buf_span.size();
|
||||
|
||||
ASSERT_EQ(encoded_field_size, test_case.expected_encoded_field.size());
|
||||
buf.resize(encoded_field_size);
|
||||
EXPECT_EQ(buf, test_case.expected_encoded_field);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
StructuredProtoTestSuiteInstantiation,
|
||||
StructuredProtoTest, // This is the name of your parameterized test
|
||||
testing::ValuesIn<StructuredProtoTestCase>({
|
||||
{
|
||||
"Varint",
|
||||
{
|
||||
42,
|
||||
StructuredProtoField::Value{
|
||||
absl::in_place_type<StructuredProtoField::Varint>,
|
||||
int32_t{23},
|
||||
},
|
||||
},
|
||||
{'\xD0', '\x02', '\x17'},
|
||||
},
|
||||
{
|
||||
"I64",
|
||||
{
|
||||
42,
|
||||
StructuredProtoField::Value{
|
||||
absl::in_place_type<StructuredProtoField::I64>,
|
||||
int64_t{23},
|
||||
},
|
||||
},
|
||||
{'\xD1', '\x02', '\x17', '\x00', '\x00', '\x00', '\x00', '\x00',
|
||||
'\x00', '\x00'},
|
||||
},
|
||||
{
|
||||
"LengthDelimited",
|
||||
{
|
||||
42,
|
||||
// Use a string_view so the terminating NUL is excluded.
|
||||
absl::string_view("Hello"),
|
||||
},
|
||||
{'\xD2', '\x02', '\x05', 'H', 'e', 'l', 'l', 'o'},
|
||||
},
|
||||
{
|
||||
"I32",
|
||||
{
|
||||
42,
|
||||
StructuredProtoField::Value{
|
||||
absl::in_place_type<StructuredProtoField::I32>,
|
||||
int32_t{23},
|
||||
},
|
||||
},
|
||||
{'\xD5', '\x02', '\x17', '\x00', '\x00', '\x00'},
|
||||
},
|
||||
}),
|
||||
[](const testing::TestParamInfo<StructuredProtoTest::ParamType>& info) {
|
||||
return info.param.test_name;
|
||||
});
|
||||
|
||||
} // namespace
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/test_actions.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
void WriteToStderrWithFilename::operator()(const absl::LogEntry& entry) const {
|
||||
std::cerr << message << " (file: " << entry.source_filename() << ")\n";
|
||||
}
|
||||
|
||||
void WriteEntryToStderr::operator()(const absl::LogEntry& entry) const {
|
||||
if (!message.empty()) std::cerr << message << "\n";
|
||||
|
||||
const std::string source_filename = absl::CHexEscape(entry.source_filename());
|
||||
const std::string source_basename = absl::CHexEscape(entry.source_basename());
|
||||
const std::string text_message = absl::CHexEscape(entry.text_message());
|
||||
const std::string encoded_message = absl::CHexEscape(entry.encoded_message());
|
||||
std::string encoded_message_str;
|
||||
std::cerr << "LogEntry{\n" //
|
||||
<< " source_filename: \"" << source_filename << "\"\n" //
|
||||
<< " source_basename: \"" << source_basename << "\"\n" //
|
||||
<< " source_line: " << entry.source_line() << "\n" //
|
||||
<< " prefix: " << (entry.prefix() ? "true\n" : "false\n") //
|
||||
<< " log_severity: " << entry.log_severity() << "\n" //
|
||||
<< " timestamp: " << entry.timestamp() << "\n" //
|
||||
<< " text_message: \"" << text_message << "\"\n" //
|
||||
<< " verbosity: " << entry.verbosity() << "\n" //
|
||||
<< " encoded_message (raw): \"" << encoded_message << "\"\n" //
|
||||
<< encoded_message_str //
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
void WriteEntryToStderr::operator()(absl::LogSeverity severity,
|
||||
absl::string_view filename,
|
||||
absl::string_view log_message) const {
|
||||
if (!message.empty()) std::cerr << message << "\n";
|
||||
const std::string source_filename = absl::CHexEscape(filename);
|
||||
const std::string text_message = absl::CHexEscape(log_message);
|
||||
std::cerr << "LogEntry{\n" //
|
||||
<< " source_filename: \"" << source_filename << "\"\n" //
|
||||
<< " log_severity: " << severity << "\n" //
|
||||
<< " text_message: \"" << text_message << "\"\n" //
|
||||
<< "}\n";
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/test_actions.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file declares Googletest's actions used in the Abseil Logging library
|
||||
// unit tests.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_TEST_ACTIONS_H_
|
||||
#define ABSL_LOG_INTERNAL_TEST_ACTIONS_H_
|
||||
|
||||
#include <iostream>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// These actions are used by the child process in a death test.
|
||||
//
|
||||
// Expectations set in the child cannot cause test failure in the parent
|
||||
// directly. Instead, the child can use these actions with
|
||||
// `EXPECT_CALL`/`WillOnce` and `ON_CALL`/`WillByDefault` (for unexpected calls)
|
||||
// to write messages to stderr that the parent can match against.
|
||||
struct WriteToStderr final {
|
||||
explicit WriteToStderr(absl::string_view m) : message(m) {}
|
||||
std::string message;
|
||||
|
||||
template <typename... Args>
|
||||
void operator()(const Args&...) const {
|
||||
std::cerr << message << std::endl;
|
||||
}
|
||||
};
|
||||
|
||||
struct WriteToStderrWithFilename final {
|
||||
explicit WriteToStderrWithFilename(absl::string_view m) : message(m) {}
|
||||
|
||||
std::string message;
|
||||
|
||||
void operator()(const absl::LogEntry& entry) const;
|
||||
};
|
||||
|
||||
struct WriteEntryToStderr final {
|
||||
explicit WriteEntryToStderr(absl::string_view m) : message(m) {}
|
||||
|
||||
std::string message = "";
|
||||
|
||||
void operator()(const absl::LogEntry& entry) const;
|
||||
void operator()(absl::LogSeverity, absl::string_view,
|
||||
absl::string_view) const;
|
||||
};
|
||||
|
||||
// See the documentation for `DeathTestValidateExpectations` above.
|
||||
// `DeathTestExpectedLogging` should be used once in a given death test, and the
|
||||
// applicable severity level is the one that should be passed to
|
||||
// `DeathTestValidateExpectations`.
|
||||
inline WriteEntryToStderr DeathTestExpectedLogging() {
|
||||
return WriteEntryToStderr{"Mock received expected entry:"};
|
||||
}
|
||||
|
||||
// `DeathTestUnexpectedLogging` should be used zero or more times to mark
|
||||
// messages that should not hit the logs as the process dies.
|
||||
inline WriteEntryToStderr DeathTestUnexpectedLogging() {
|
||||
return WriteEntryToStderr{"Mock received unexpected entry:"};
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_TEST_ACTIONS_H_
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
|
||||
#ifdef __Fuchsia__
|
||||
#include <zircon/syscalls.h>
|
||||
#endif
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/initialize.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// Returns false if the specified severity level is disabled by
|
||||
// `ABSL_MIN_LOG_LEVEL` or `absl::MinLogLevel()`.
|
||||
bool LoggingEnabledAt(absl::LogSeverity severity) {
|
||||
return severity >= kAbslMinLogLevel && severity >= absl::MinLogLevel();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Googletest Death Test Predicates
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
bool DiedOfFatal(int exit_status) {
|
||||
#if defined(_WIN32)
|
||||
// Depending on NDEBUG and (configuration?) MSVC's abort either results
|
||||
// in error code 3 (SIGABRT) or error code 0x80000003 (breakpoint
|
||||
// triggered).
|
||||
return ::testing::ExitedWithCode(3)(exit_status & 0x7fffffff);
|
||||
#elif defined(__Fuchsia__)
|
||||
// The Fuchsia death test implementation kill()'s the process when it detects
|
||||
// an exception, so it should exit with the corresponding code. See
|
||||
// FuchsiaDeathTest::Wait().
|
||||
return ::testing::ExitedWithCode(ZX_TASK_RETCODE_SYSCALL_KILL)(exit_status);
|
||||
#elif defined(__ANDROID__) && defined(__aarch64__)
|
||||
// These are all run under a qemu config that eats died-due-to-signal exit
|
||||
// statuses.
|
||||
return true;
|
||||
#else
|
||||
return ::testing::KilledBySignal(SIGABRT)(exit_status);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool DiedOfQFatal(int exit_status) {
|
||||
return ::testing::ExitedWithCode(1)(exit_status);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Helper for Log initialization in test
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void LogTestEnvironment::SetUp() {
|
||||
if (!absl::log_internal::IsInitialized()) {
|
||||
absl::InitializeLog();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/test_helpers.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file declares testing helpers for the logging library.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_TEST_HELPERS_H_
|
||||
#define ABSL_LOG_INTERNAL_TEST_HELPERS_H_
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/globals.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
// `ABSL_MIN_LOG_LEVEL` can't be used directly since it is not always defined.
|
||||
constexpr auto kAbslMinLogLevel =
|
||||
#ifdef ABSL_MIN_LOG_LEVEL
|
||||
static_cast<absl::LogSeverityAtLeast>(ABSL_MIN_LOG_LEVEL);
|
||||
#else
|
||||
absl::LogSeverityAtLeast::kInfo;
|
||||
#endif
|
||||
|
||||
// Returns false if the specified severity level is disabled by
|
||||
// `ABSL_MIN_LOG_LEVEL` or `absl::MinLogLevel()`.
|
||||
bool LoggingEnabledAt(absl::LogSeverity severity);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Googletest Death Test Predicates
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
|
||||
bool DiedOfFatal(int exit_status);
|
||||
bool DiedOfQFatal(int exit_status);
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Helper for Log initialization in test
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class LogTestEnvironment : public ::testing::Environment {
|
||||
public:
|
||||
~LogTestEnvironment() override = default;
|
||||
|
||||
void SetUp() override;
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_TEST_HELPERS_H_
|
||||
216
TMessagesProj/jni/voip/webrtc/absl/log/internal/test_matchers.cc
Normal file
216
TMessagesProj/jni/voip/webrtc/absl/log/internal/test_matchers.cc
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
|
||||
#include <ostream>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/clock.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
namespace {
|
||||
using ::testing::_;
|
||||
using ::testing::AllOf;
|
||||
using ::testing::Ge;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::MakeMatcher;
|
||||
using ::testing::Matcher;
|
||||
using ::testing::MatcherInterface;
|
||||
using ::testing::MatchResultListener;
|
||||
using ::testing::Not;
|
||||
using ::testing::Property;
|
||||
using ::testing::ResultOf;
|
||||
using ::testing::Truly;
|
||||
|
||||
class AsStringImpl final
|
||||
: public MatcherInterface<absl::string_view> {
|
||||
public:
|
||||
explicit AsStringImpl(
|
||||
const Matcher<const std::string&>& str_matcher)
|
||||
: str_matcher_(str_matcher) {}
|
||||
bool MatchAndExplain(
|
||||
absl::string_view actual,
|
||||
MatchResultListener* listener) const override {
|
||||
return str_matcher_.MatchAndExplain(std::string(actual), listener);
|
||||
}
|
||||
void DescribeTo(std::ostream* os) const override {
|
||||
return str_matcher_.DescribeTo(os);
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const override {
|
||||
return str_matcher_.DescribeNegationTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
const Matcher<const std::string&> str_matcher_;
|
||||
};
|
||||
|
||||
class MatchesOstreamImpl final
|
||||
: public MatcherInterface<absl::string_view> {
|
||||
public:
|
||||
explicit MatchesOstreamImpl(std::string expected)
|
||||
: expected_(std::move(expected)) {}
|
||||
bool MatchAndExplain(absl::string_view actual,
|
||||
MatchResultListener*) const override {
|
||||
return actual == expected_;
|
||||
}
|
||||
void DescribeTo(std::ostream* os) const override {
|
||||
*os << "matches the contents of the ostringstream, which are \""
|
||||
<< expected_ << "\"";
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const override {
|
||||
*os << "does not match the contents of the ostringstream, which are \""
|
||||
<< expected_ << "\"";
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string expected_;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
Matcher<absl::string_view> AsString(
|
||||
const Matcher<const std::string&>& str_matcher) {
|
||||
return MakeMatcher(new AsStringImpl(str_matcher));
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> SourceFilename(
|
||||
const Matcher<absl::string_view>& source_filename) {
|
||||
return Property("source_filename", &absl::LogEntry::source_filename,
|
||||
source_filename);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> SourceBasename(
|
||||
const Matcher<absl::string_view>& source_basename) {
|
||||
return Property("source_basename", &absl::LogEntry::source_basename,
|
||||
source_basename);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> SourceLine(
|
||||
const Matcher<int>& source_line) {
|
||||
return Property("source_line", &absl::LogEntry::source_line, source_line);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> Prefix(
|
||||
const Matcher<bool>& prefix) {
|
||||
return Property("prefix", &absl::LogEntry::prefix, prefix);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> LogSeverity(
|
||||
const Matcher<absl::LogSeverity>& log_severity) {
|
||||
return Property("log_severity", &absl::LogEntry::log_severity, log_severity);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> Timestamp(
|
||||
const Matcher<absl::Time>& timestamp) {
|
||||
return Property("timestamp", &absl::LogEntry::timestamp, timestamp);
|
||||
}
|
||||
|
||||
Matcher<absl::Time> InMatchWindow() {
|
||||
return AllOf(Ge(absl::Now()),
|
||||
Truly([](absl::Time arg) { return arg <= absl::Now(); }));
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> ThreadID(
|
||||
const Matcher<absl::LogEntry::tid_t>& tid) {
|
||||
return Property("tid", &absl::LogEntry::tid, tid);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> TextMessageWithPrefixAndNewline(
|
||||
const Matcher<absl::string_view>&
|
||||
text_message_with_prefix_and_newline) {
|
||||
return Property("text_message_with_prefix_and_newline",
|
||||
&absl::LogEntry::text_message_with_prefix_and_newline,
|
||||
text_message_with_prefix_and_newline);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> TextMessageWithPrefix(
|
||||
const Matcher<absl::string_view>& text_message_with_prefix) {
|
||||
return Property("text_message_with_prefix",
|
||||
&absl::LogEntry::text_message_with_prefix,
|
||||
text_message_with_prefix);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> TextMessage(
|
||||
const Matcher<absl::string_view>& text_message) {
|
||||
return Property("text_message", &absl::LogEntry::text_message, text_message);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> TextPrefix(
|
||||
const Matcher<absl::string_view>& text_prefix) {
|
||||
return ResultOf(
|
||||
[](const absl::LogEntry& entry) {
|
||||
absl::string_view msg = entry.text_message_with_prefix();
|
||||
msg.remove_suffix(entry.text_message().size());
|
||||
return msg;
|
||||
},
|
||||
text_prefix);
|
||||
}
|
||||
Matcher<const absl::LogEntry&> RawEncodedMessage(
|
||||
const Matcher<absl::string_view>& raw_encoded_message) {
|
||||
return Property("encoded_message", &absl::LogEntry::encoded_message,
|
||||
raw_encoded_message);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> Verbosity(
|
||||
const Matcher<int>& verbosity) {
|
||||
return Property("verbosity", &absl::LogEntry::verbosity, verbosity);
|
||||
}
|
||||
|
||||
Matcher<const absl::LogEntry&> Stacktrace(
|
||||
const Matcher<absl::string_view>& stacktrace) {
|
||||
return Property("stacktrace", &absl::LogEntry::stacktrace, stacktrace);
|
||||
}
|
||||
|
||||
Matcher<absl::string_view> MatchesOstream(
|
||||
const std::ostringstream& stream) {
|
||||
return MakeMatcher(new MatchesOstreamImpl(stream.str()));
|
||||
}
|
||||
|
||||
// We need to validate what is and isn't logged as the process dies due to
|
||||
// `FATAL`, `QFATAL`, `CHECK`, etc., but assertions inside a death test
|
||||
// subprocess don't directly affect the pass/fail status of the parent process.
|
||||
// Instead, we use the mock actions `DeathTestExpectedLogging` and
|
||||
// `DeathTestUnexpectedLogging` to write specific phrases to `stderr` that we
|
||||
// can validate in the parent process using this matcher.
|
||||
Matcher<const std::string&> DeathTestValidateExpectations() {
|
||||
if (log_internal::LoggingEnabledAt(absl::LogSeverity::kFatal)) {
|
||||
return Matcher<const std::string&>(
|
||||
AllOf(HasSubstr("Mock received expected entry"),
|
||||
Not(HasSubstr("Mock received unexpected entry"))));
|
||||
}
|
||||
// If `FATAL` logging is disabled, neither message should have been written.
|
||||
return Matcher<const std::string&>(
|
||||
AllOf(Not(HasSubstr("Mock received expected entry")),
|
||||
Not(HasSubstr("Mock received unexpected entry"))));
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/test_matchers.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This file declares Googletest's matchers used in the Abseil Logging library
|
||||
// unit tests.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_TEST_MATCHERS_H_
|
||||
#define ABSL_LOG_INTERNAL_TEST_MATCHERS_H_
|
||||
|
||||
#include <iosfwd>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
// In some configurations, Googletest's string matchers (e.g.
|
||||
// `::testing::EndsWith`) need help to match `absl::string_view`.
|
||||
::testing::Matcher<absl::string_view> AsString(
|
||||
const ::testing::Matcher<const std::string&>& str_matcher);
|
||||
|
||||
// These matchers correspond to the components of `absl::LogEntry`.
|
||||
::testing::Matcher<const absl::LogEntry&> SourceFilename(
|
||||
const ::testing::Matcher<absl::string_view>& source_filename);
|
||||
::testing::Matcher<const absl::LogEntry&> SourceBasename(
|
||||
const ::testing::Matcher<absl::string_view>& source_basename);
|
||||
// Be careful with this one; multi-line statements using `__LINE__` evaluate
|
||||
// differently on different platforms. In particular, the MSVC implementation
|
||||
// of `EXPECT_DEATH` returns the line number of the macro expansion to all lines
|
||||
// within the code block that's expected to die.
|
||||
::testing::Matcher<const absl::LogEntry&> SourceLine(
|
||||
const ::testing::Matcher<int>& source_line);
|
||||
::testing::Matcher<const absl::LogEntry&> Prefix(
|
||||
const ::testing::Matcher<bool>& prefix);
|
||||
::testing::Matcher<const absl::LogEntry&> LogSeverity(
|
||||
const ::testing::Matcher<absl::LogSeverity>& log_severity);
|
||||
::testing::Matcher<const absl::LogEntry&> Timestamp(
|
||||
const ::testing::Matcher<absl::Time>& timestamp);
|
||||
// Matches if the `LogEntry`'s timestamp falls after the instantiation of this
|
||||
// matcher and before its execution, as is normal when used with EXPECT_CALL.
|
||||
::testing::Matcher<absl::Time> InMatchWindow();
|
||||
::testing::Matcher<const absl::LogEntry&> ThreadID(
|
||||
const ::testing::Matcher<absl::LogEntry::tid_t>&);
|
||||
::testing::Matcher<const absl::LogEntry&> TextMessageWithPrefixAndNewline(
|
||||
const ::testing::Matcher<absl::string_view>&
|
||||
text_message_with_prefix_and_newline);
|
||||
::testing::Matcher<const absl::LogEntry&> TextMessageWithPrefix(
|
||||
const ::testing::Matcher<absl::string_view>& text_message_with_prefix);
|
||||
::testing::Matcher<const absl::LogEntry&> TextMessage(
|
||||
const ::testing::Matcher<absl::string_view>& text_message);
|
||||
::testing::Matcher<const absl::LogEntry&> TextPrefix(
|
||||
const ::testing::Matcher<absl::string_view>& text_prefix);
|
||||
::testing::Matcher<const absl::LogEntry&> Verbosity(
|
||||
const ::testing::Matcher<int>& verbosity);
|
||||
::testing::Matcher<const absl::LogEntry&> Stacktrace(
|
||||
const ::testing::Matcher<absl::string_view>& stacktrace);
|
||||
// Behaves as `Eq(stream.str())`, but produces better failure messages.
|
||||
::testing::Matcher<absl::string_view> MatchesOstream(
|
||||
const std::ostringstream& stream);
|
||||
::testing::Matcher<const std::string&> DeathTestValidateExpectations();
|
||||
|
||||
::testing::Matcher<const absl::LogEntry&> RawEncodedMessage(
|
||||
const ::testing::Matcher<absl::string_view>& raw_encoded_message);
|
||||
#define ENCODED_MESSAGE(message_matcher) ::testing::_
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_TEST_MATCHERS_H_
|
||||
347
TMessagesProj/jni/voip/webrtc/absl/log/internal/vlog_config.cc
Normal file
347
TMessagesProj/jni/voip/webrtc/absl/log/internal/vlog_config.cc
Normal file
|
|
@ -0,0 +1,347 @@
|
|||
// Copyright 2022 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/internal/vlog_config.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/const_init.h"
|
||||
#include "absl/base/internal/spinlock.h"
|
||||
#include "absl/base/no_destructor.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/log/internal/fnmatch.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/strings/strip.h"
|
||||
#include "absl/synchronization/mutex.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
namespace {
|
||||
bool ModuleIsPath(absl::string_view module_pattern) {
|
||||
#ifdef _WIN32
|
||||
return module_pattern.find_first_of("/\\") != module_pattern.npos;
|
||||
#else
|
||||
return module_pattern.find('/') != module_pattern.npos;
|
||||
#endif
|
||||
}
|
||||
} // namespace
|
||||
|
||||
bool VLogSite::SlowIsEnabled(int stale_v, int level) {
|
||||
if (ABSL_PREDICT_TRUE(stale_v != kUninitialized)) {
|
||||
// Because of the prerequisites to this function, we know that stale_v is
|
||||
// either uninitialized or >= level. If it's not uninitialized, that means
|
||||
// it must be >= level, thus we should log.
|
||||
return true;
|
||||
}
|
||||
stale_v = log_internal::RegisterAndInitialize(this);
|
||||
return ABSL_PREDICT_FALSE(stale_v >= level);
|
||||
}
|
||||
|
||||
bool VLogSite::SlowIsEnabled0(int stale_v) { return SlowIsEnabled(stale_v, 0); }
|
||||
bool VLogSite::SlowIsEnabled1(int stale_v) { return SlowIsEnabled(stale_v, 1); }
|
||||
bool VLogSite::SlowIsEnabled2(int stale_v) { return SlowIsEnabled(stale_v, 2); }
|
||||
bool VLogSite::SlowIsEnabled3(int stale_v) { return SlowIsEnabled(stale_v, 3); }
|
||||
bool VLogSite::SlowIsEnabled4(int stale_v) { return SlowIsEnabled(stale_v, 4); }
|
||||
bool VLogSite::SlowIsEnabled5(int stale_v) { return SlowIsEnabled(stale_v, 5); }
|
||||
|
||||
namespace {
|
||||
struct VModuleInfo final {
|
||||
std::string module_pattern;
|
||||
bool module_is_path; // i.e. it contains a path separator.
|
||||
int vlog_level;
|
||||
|
||||
// Allocates memory.
|
||||
VModuleInfo(absl::string_view module_pattern_arg, bool module_is_path_arg,
|
||||
int vlog_level_arg)
|
||||
: module_pattern(std::string(module_pattern_arg)),
|
||||
module_is_path(module_is_path_arg),
|
||||
vlog_level(vlog_level_arg) {}
|
||||
};
|
||||
|
||||
// `mutex` guards all of the data structures that aren't lock-free.
|
||||
// To avoid problems with the heap checker which calls into `VLOG`, `mutex` must
|
||||
// be a `SpinLock` that prevents fiber scheduling instead of a `Mutex`.
|
||||
ABSL_CONST_INIT absl::base_internal::SpinLock mutex(
|
||||
absl::kConstInit, absl::base_internal::SCHEDULE_KERNEL_ONLY);
|
||||
|
||||
// `GetUpdateSitesMutex()` serializes updates to all of the sites (i.e. those in
|
||||
// `site_list_head`) themselves.
|
||||
absl::Mutex* GetUpdateSitesMutex() {
|
||||
// Chromium requires no global destructors, so we can't use the
|
||||
// absl::kConstInit idiom since absl::Mutex as a non-trivial destructor.
|
||||
static absl::NoDestructor<absl::Mutex> update_sites_mutex ABSL_ACQUIRED_AFTER(
|
||||
mutex);
|
||||
return update_sites_mutex.get();
|
||||
}
|
||||
|
||||
ABSL_CONST_INIT int global_v ABSL_GUARDED_BY(mutex) = 0;
|
||||
// `site_list_head` is the head of a singly-linked list. Traversal, insertion,
|
||||
// and reads are atomic, so no locks are required, but updates to existing
|
||||
// elements are guarded by `GetUpdateSitesMutex()`.
|
||||
ABSL_CONST_INIT std::atomic<VLogSite*> site_list_head{nullptr};
|
||||
ABSL_CONST_INIT std::vector<VModuleInfo>* vmodule_info ABSL_GUARDED_BY(mutex)
|
||||
ABSL_PT_GUARDED_BY(mutex){nullptr};
|
||||
|
||||
// Only used for lisp.
|
||||
ABSL_CONST_INIT std::vector<std::function<void()>>* update_callbacks
|
||||
ABSL_GUARDED_BY(GetUpdateSitesMutex())
|
||||
ABSL_PT_GUARDED_BY(GetUpdateSitesMutex()){nullptr};
|
||||
|
||||
// Allocates memory.
|
||||
std::vector<VModuleInfo>& get_vmodule_info()
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
|
||||
if (!vmodule_info) vmodule_info = new std::vector<VModuleInfo>;
|
||||
return *vmodule_info;
|
||||
}
|
||||
|
||||
// Does not allocate or take locks.
|
||||
int VLogLevel(absl::string_view file, const std::vector<VModuleInfo>* infos,
|
||||
int current_global_v) {
|
||||
// `infos` is null during a call to `VLOG` prior to setting `vmodule` (e.g. by
|
||||
// parsing flags). We can't allocate in `VLOG`, so we treat null as empty
|
||||
// here and press on.
|
||||
if (!infos || infos->empty()) return current_global_v;
|
||||
// Get basename for file
|
||||
absl::string_view basename = file;
|
||||
{
|
||||
const size_t sep = basename.rfind('/');
|
||||
if (sep != basename.npos) {
|
||||
basename.remove_prefix(sep + 1);
|
||||
#ifdef _WIN32
|
||||
} else {
|
||||
const size_t sep = basename.rfind('\\');
|
||||
if (sep != basename.npos) basename.remove_prefix(sep + 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
absl::string_view stem = file, stem_basename = basename;
|
||||
{
|
||||
const size_t sep = stem_basename.find('.');
|
||||
if (sep != stem_basename.npos) {
|
||||
stem.remove_suffix(stem_basename.size() - sep);
|
||||
stem_basename.remove_suffix(stem_basename.size() - sep);
|
||||
}
|
||||
if (absl::ConsumeSuffix(&stem_basename, "-inl")) {
|
||||
stem.remove_suffix(absl::string_view("-inl").size());
|
||||
}
|
||||
}
|
||||
for (const auto& info : *infos) {
|
||||
if (info.module_is_path) {
|
||||
// If there are any slashes in the pattern, try to match the full
|
||||
// name.
|
||||
if (FNMatch(info.module_pattern, stem)) {
|
||||
return info.vlog_level == kUseFlag ? current_global_v : info.vlog_level;
|
||||
}
|
||||
} else if (FNMatch(info.module_pattern, stem_basename)) {
|
||||
return info.vlog_level == kUseFlag ? current_global_v : info.vlog_level;
|
||||
}
|
||||
}
|
||||
|
||||
return current_global_v;
|
||||
}
|
||||
|
||||
// Allocates memory.
|
||||
int AppendVModuleLocked(absl::string_view module_pattern, int log_level)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
|
||||
for (const auto& info : get_vmodule_info()) {
|
||||
if (FNMatch(info.module_pattern, module_pattern)) {
|
||||
// This is a memory optimization to avoid storing patterns that will never
|
||||
// match due to exit early semantics. Primarily optimized for our own unit
|
||||
// tests.
|
||||
return info.vlog_level;
|
||||
}
|
||||
}
|
||||
bool module_is_path = ModuleIsPath(module_pattern);
|
||||
get_vmodule_info().emplace_back(std::string(module_pattern), module_is_path,
|
||||
log_level);
|
||||
return global_v;
|
||||
}
|
||||
|
||||
// Allocates memory.
|
||||
int PrependVModuleLocked(absl::string_view module_pattern, int log_level)
|
||||
ABSL_EXCLUSIVE_LOCKS_REQUIRED(mutex) {
|
||||
absl::optional<int> old_log_level;
|
||||
for (const auto& info : get_vmodule_info()) {
|
||||
if (FNMatch(info.module_pattern, module_pattern)) {
|
||||
old_log_level = info.vlog_level;
|
||||
break;
|
||||
}
|
||||
}
|
||||
bool module_is_path = ModuleIsPath(module_pattern);
|
||||
auto iter = get_vmodule_info().emplace(get_vmodule_info().cbegin(),
|
||||
std::string(module_pattern),
|
||||
module_is_path, log_level);
|
||||
|
||||
// This is a memory optimization to avoid storing patterns that will never
|
||||
// match due to exit early semantics. Primarily optimized for our own unit
|
||||
// tests.
|
||||
get_vmodule_info().erase(
|
||||
std::remove_if(++iter, get_vmodule_info().end(),
|
||||
[module_pattern](const VModuleInfo& info) {
|
||||
// Remove the previous pattern if it is less generic than
|
||||
// the new one. For example, if the new pattern
|
||||
// `module_pattern` is "foo*" and the previous pattern
|
||||
// `info.module_pattern` is "foo", we should remove the
|
||||
// previous pattern. Because the new pattern "foo*" will
|
||||
// match all the files that the previous pattern "foo"
|
||||
// matches.
|
||||
return FNMatch(module_pattern, info.module_pattern);
|
||||
}),
|
||||
get_vmodule_info().cend());
|
||||
return old_log_level.value_or(global_v);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
int VLogLevel(absl::string_view file) ABSL_LOCKS_EXCLUDED(mutex) {
|
||||
absl::base_internal::SpinLockHolder l(&mutex);
|
||||
return VLogLevel(file, vmodule_info, global_v);
|
||||
}
|
||||
|
||||
int RegisterAndInitialize(VLogSite* v) ABSL_LOCKS_EXCLUDED(mutex) {
|
||||
// std::memory_order_seq_cst is overkill in this function, but given that this
|
||||
// path is intended to be slow, it's not worth the brain power to relax that.
|
||||
VLogSite* h = site_list_head.load(std::memory_order_seq_cst);
|
||||
|
||||
VLogSite* old = nullptr;
|
||||
if (v->next_.compare_exchange_strong(old, h, std::memory_order_seq_cst,
|
||||
std::memory_order_seq_cst)) {
|
||||
// Multiple threads may attempt to register this site concurrently.
|
||||
// By successfully setting `v->next` this thread commits to being *the*
|
||||
// thread that installs `v` in the list.
|
||||
while (!site_list_head.compare_exchange_weak(
|
||||
h, v, std::memory_order_seq_cst, std::memory_order_seq_cst)) {
|
||||
v->next_.store(h, std::memory_order_seq_cst);
|
||||
}
|
||||
}
|
||||
|
||||
int old_v = VLogSite::kUninitialized;
|
||||
int new_v = VLogLevel(v->file_);
|
||||
// No loop, if someone else set this, we should respect their evaluation of
|
||||
// `VLogLevel`. This may mean we return a stale `v`, but `v` itself will
|
||||
// always arrive at the freshest value. Otherwise, we could be writing a
|
||||
// stale value and clobbering the fresher one.
|
||||
if (v->v_.compare_exchange_strong(old_v, new_v, std::memory_order_seq_cst,
|
||||
std::memory_order_seq_cst)) {
|
||||
return new_v;
|
||||
}
|
||||
return old_v;
|
||||
}
|
||||
|
||||
void UpdateVLogSites() ABSL_UNLOCK_FUNCTION(mutex)
|
||||
ABSL_LOCKS_EXCLUDED(GetUpdateSitesMutex()) {
|
||||
std::vector<VModuleInfo> infos = get_vmodule_info();
|
||||
int current_global_v = global_v;
|
||||
// We need to grab `GetUpdateSitesMutex()` before we release `mutex` to ensure
|
||||
// that updates are not interleaved (resulting in an inconsistent final state)
|
||||
// and to ensure that the final state in the sites matches the final state of
|
||||
// `vmodule_info`. We unlock `mutex` to ensure that uninitialized sites don't
|
||||
// have to wait on all updates in order to acquire `mutex` and initialize
|
||||
// themselves.
|
||||
absl::MutexLock ul(GetUpdateSitesMutex());
|
||||
mutex.Unlock();
|
||||
VLogSite* n = site_list_head.load(std::memory_order_seq_cst);
|
||||
// Because sites are added to the list in the order they are executed, there
|
||||
// tend to be clusters of entries with the same file.
|
||||
const char* last_file = nullptr;
|
||||
int last_file_level = 0;
|
||||
while (n != nullptr) {
|
||||
if (n->file_ != last_file) {
|
||||
last_file = n->file_;
|
||||
last_file_level = VLogLevel(n->file_, &infos, current_global_v);
|
||||
}
|
||||
n->v_.store(last_file_level, std::memory_order_seq_cst);
|
||||
n = n->next_.load(std::memory_order_seq_cst);
|
||||
}
|
||||
if (update_callbacks) {
|
||||
for (auto& cb : *update_callbacks) {
|
||||
cb();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateVModule(absl::string_view vmodule)
|
||||
ABSL_LOCKS_EXCLUDED(mutex, GetUpdateSitesMutex()) {
|
||||
std::vector<std::pair<absl::string_view, int>> glob_levels;
|
||||
for (absl::string_view glob_level : absl::StrSplit(vmodule, ',')) {
|
||||
const size_t eq = glob_level.rfind('=');
|
||||
if (eq == glob_level.npos) continue;
|
||||
const absl::string_view glob = glob_level.substr(0, eq);
|
||||
int level;
|
||||
if (!absl::SimpleAtoi(glob_level.substr(eq + 1), &level)) continue;
|
||||
glob_levels.emplace_back(glob, level);
|
||||
}
|
||||
mutex.Lock(); // Unlocked by UpdateVLogSites().
|
||||
get_vmodule_info().clear();
|
||||
for (const auto& it : glob_levels) {
|
||||
const absl::string_view glob = it.first;
|
||||
const int level = it.second;
|
||||
AppendVModuleLocked(glob, level);
|
||||
}
|
||||
UpdateVLogSites();
|
||||
}
|
||||
|
||||
int UpdateGlobalVLogLevel(int v)
|
||||
ABSL_LOCKS_EXCLUDED(mutex, GetUpdateSitesMutex()) {
|
||||
mutex.Lock(); // Unlocked by UpdateVLogSites().
|
||||
const int old_global_v = global_v;
|
||||
if (v == global_v) {
|
||||
mutex.Unlock();
|
||||
return old_global_v;
|
||||
}
|
||||
global_v = v;
|
||||
UpdateVLogSites();
|
||||
return old_global_v;
|
||||
}
|
||||
|
||||
int PrependVModule(absl::string_view module_pattern, int log_level)
|
||||
ABSL_LOCKS_EXCLUDED(mutex, GetUpdateSitesMutex()) {
|
||||
mutex.Lock(); // Unlocked by UpdateVLogSites().
|
||||
int old_v = PrependVModuleLocked(module_pattern, log_level);
|
||||
UpdateVLogSites();
|
||||
return old_v;
|
||||
}
|
||||
|
||||
void OnVLogVerbosityUpdate(std::function<void()> cb)
|
||||
ABSL_LOCKS_EXCLUDED(GetUpdateSitesMutex()) {
|
||||
absl::MutexLock ul(GetUpdateSitesMutex());
|
||||
if (!update_callbacks)
|
||||
update_callbacks = new std::vector<std::function<void()>>;
|
||||
update_callbacks->push_back(std::move(cb));
|
||||
}
|
||||
|
||||
VLogSite* SetVModuleListHeadForTestOnly(VLogSite* v) {
|
||||
return site_list_head.exchange(v, std::memory_order_seq_cst);
|
||||
}
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
163
TMessagesProj/jni/voip/webrtc/absl/log/internal/vlog_config.h
Normal file
163
TMessagesProj/jni/voip/webrtc/absl/log/internal/vlog_config.h
Normal file
|
|
@ -0,0 +1,163 @@
|
|||
// Copyright 2022 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// vlog_config.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header file defines `VLogSite`, a public primitive that represents
|
||||
// a callsite for the `VLOG` family of macros and related libraries.
|
||||
// It also declares and defines multiple internal utilities used to implement
|
||||
// `VLOG`, such as `VLogSiteManager`.
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
|
||||
#define ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
|
||||
|
||||
// IWYU pragma: private, include "absl/log/log.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <limits>
|
||||
#include <type_traits>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/optimization.h"
|
||||
#include "absl/base/thread_annotations.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
class SyntheticBinary;
|
||||
class VLogSite;
|
||||
|
||||
int RegisterAndInitialize(VLogSite* v);
|
||||
void UpdateVLogSites();
|
||||
constexpr int kUseFlag = (std::numeric_limits<int16_t>::min)();
|
||||
|
||||
// Represents a unique callsite for a `VLOG()` or `VLOG_IS_ON()` call.
|
||||
//
|
||||
// Libraries that provide `VLOG`-like functionality should use this to
|
||||
// efficiently handle --vmodule.
|
||||
//
|
||||
// VLogSite objects must not be destroyed until the program exits. Doing so will
|
||||
// probably yield nasty segfaults in VLogSiteManager::UpdateLogSites(). The
|
||||
// recommendation is to make all such objects function-local statics.
|
||||
class VLogSite final {
|
||||
public:
|
||||
// `f` must not be destroyed until the program exits.
|
||||
explicit constexpr VLogSite(const char* f)
|
||||
: file_(f), v_(kUninitialized), next_(nullptr) {}
|
||||
VLogSite(const VLogSite&) = delete;
|
||||
VLogSite& operator=(const VLogSite&) = delete;
|
||||
|
||||
// Inlining the function yields a ~3x performance improvement at the cost of a
|
||||
// 1.5x code size increase at the call site.
|
||||
// Takes locks but does not allocate memory.
|
||||
ABSL_ATTRIBUTE_ALWAYS_INLINE
|
||||
bool IsEnabled(int level) {
|
||||
int stale_v = v_.load(std::memory_order_relaxed);
|
||||
if (ABSL_PREDICT_TRUE(level > stale_v)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// We put everything other than the fast path, i.e. vlogging is initialized
|
||||
// but not on, behind an out-of-line function to reduce code size.
|
||||
// "level" is almost always a call-site constant, so we can save a bit
|
||||
// of code space by special-casing for a few common levels.
|
||||
#if ABSL_HAVE_BUILTIN(__builtin_constant_p) || defined(__GNUC__)
|
||||
if (__builtin_constant_p(level)) {
|
||||
if (level == 0) return SlowIsEnabled0(stale_v);
|
||||
if (level == 1) return SlowIsEnabled1(stale_v);
|
||||
if (level == 2) return SlowIsEnabled2(stale_v);
|
||||
if (level == 3) return SlowIsEnabled3(stale_v);
|
||||
if (level == 4) return SlowIsEnabled4(stale_v);
|
||||
if (level == 5) return SlowIsEnabled5(stale_v);
|
||||
}
|
||||
#endif
|
||||
return SlowIsEnabled(stale_v, level);
|
||||
}
|
||||
|
||||
private:
|
||||
friend int log_internal::RegisterAndInitialize(VLogSite* v);
|
||||
friend void log_internal::UpdateVLogSites();
|
||||
friend class log_internal::SyntheticBinary;
|
||||
static constexpr int kUninitialized = (std::numeric_limits<int>::max)();
|
||||
|
||||
// SlowIsEnabled performs slower checks to determine whether a log site is
|
||||
// enabled. Because it is expected to be called somewhat rarely
|
||||
// (comparatively), it is not inlined to save on code size.
|
||||
//
|
||||
// Prerequisites to calling SlowIsEnabled:
|
||||
// 1) stale_v is uninitialized OR
|
||||
// 2) stale_v is initialized and >= level (meaning we must log).
|
||||
// Takes locks but does not allocate memory.
|
||||
ABSL_ATTRIBUTE_NOINLINE
|
||||
bool SlowIsEnabled(int stale_v, int level);
|
||||
ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled0(int stale_v);
|
||||
ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled1(int stale_v);
|
||||
ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled2(int stale_v);
|
||||
ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled3(int stale_v);
|
||||
ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled4(int stale_v);
|
||||
ABSL_ATTRIBUTE_NOINLINE bool SlowIsEnabled5(int stale_v);
|
||||
|
||||
// This object is too size-sensitive to use absl::string_view.
|
||||
const char* const file_;
|
||||
std::atomic<int> v_;
|
||||
std::atomic<VLogSite*> next_;
|
||||
};
|
||||
static_assert(std::is_trivially_destructible<VLogSite>::value,
|
||||
"VLogSite must be trivially destructible");
|
||||
|
||||
// Returns the current verbose log level of `file`.
|
||||
// Does not allocate memory.
|
||||
int VLogLevel(absl::string_view file);
|
||||
|
||||
// Registers a site `v` to get updated as `vmodule` and `v` change. Also
|
||||
// initializes the site based on their current values, and returns that result.
|
||||
// Does not allocate memory.
|
||||
int RegisterAndInitialize(VLogSite* v);
|
||||
|
||||
// Allocates memory.
|
||||
void UpdateVLogSites();
|
||||
|
||||
// Completely overwrites the saved value of `vmodule`.
|
||||
// Allocates memory.
|
||||
void UpdateVModule(absl::string_view vmodule);
|
||||
|
||||
// Updates the global verbosity level to `v` and returns the prior value.
|
||||
// Allocates memory.
|
||||
int UpdateGlobalVLogLevel(int v);
|
||||
|
||||
// Atomically prepends `module_pattern=log_level` to the start of vmodule.
|
||||
// Returns the prior value for `module_pattern` if there was an exact match and
|
||||
// `global_v` otherwise.
|
||||
// Allocates memory.
|
||||
int PrependVModule(absl::string_view module_pattern, int log_level);
|
||||
|
||||
// Registers `on_update` to be called whenever `v` or `vmodule` change.
|
||||
// Allocates memory.
|
||||
void OnVLogVerbosityUpdate(std::function<void()> cb);
|
||||
|
||||
// Does not allocate memory.
|
||||
VLogSite* SetVModuleListHeadForTestOnly(VLogSite* v);
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_VLOG_CONFIG_H_
|
||||
|
|
@ -0,0 +1,187 @@
|
|||
// Copyright 2022 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <cstddef>
|
||||
#include <cstring>
|
||||
#include <memory>
|
||||
#include <new>
|
||||
#include <random>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/container/internal/layout.h"
|
||||
#include "absl/log/internal/vlog_config.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/random/distributions.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
// Performance of `UpdateLogSites` depends upon the number and organization of
|
||||
// `VLogSite`s in the program. We can synthesize some on the heap to mimic
|
||||
// their layout and linkage in static data.
|
||||
class SyntheticBinary {
|
||||
public:
|
||||
explicit SyntheticBinary(const size_t num_tus,
|
||||
const size_t max_extra_static_data_bytes_per_tu,
|
||||
const size_t max_sites_per_tu,
|
||||
const int num_shuffles) {
|
||||
per_tu_data_.reserve(num_tus);
|
||||
auto sites = absl::make_unique<VLogSite *[]>(num_tus * max_sites_per_tu);
|
||||
for (size_t i = 0; i < num_tus; i++) {
|
||||
const std::string filename =
|
||||
absl::StrCat("directory-", i / 100, "/subdirectory-", i % 100 / 10,
|
||||
"/file-", i % 10, ".cc");
|
||||
container_internal::Layout<char, VLogSite, char> layout(
|
||||
filename.size() + 1,
|
||||
absl::LogUniform<size_t>(bitgen_, 1, max_sites_per_tu),
|
||||
absl::LogUniform<size_t>(bitgen_, 0,
|
||||
max_extra_static_data_bytes_per_tu));
|
||||
auto buf = absl::make_unique<char[]>(layout.AllocSize());
|
||||
layout.PoisonPadding(buf.get());
|
||||
memcpy(layout.Pointer<0>(buf.get()), filename.c_str(),
|
||||
filename.size() + 1);
|
||||
for (VLogSite &site : layout.Slice<1>(buf.get())) {
|
||||
sites[num_sites_++] =
|
||||
new (&site) VLogSite(layout.Pointer<0>(buf.get()));
|
||||
// The last one is a dangling pointer but will be fixed below.
|
||||
site.next_.store(&site + 1, std::memory_order_seq_cst);
|
||||
}
|
||||
num_extra_static_data_bytes_ += layout.Size<2>();
|
||||
per_tu_data_.push_back(PerTU{layout, std::move(buf)});
|
||||
}
|
||||
// Now link the files together back-to-front into a circular list.
|
||||
for (size_t i = 0; i < num_tus; i++) {
|
||||
auto &tu = per_tu_data_[i];
|
||||
auto &next_tu = per_tu_data_[(i + 1) % num_tus];
|
||||
tu.layout.Slice<1>(tu.buf.get())
|
||||
.back()
|
||||
.next_.store(next_tu.layout.Pointer<1>(next_tu.buf.get()),
|
||||
std::memory_order_seq_cst);
|
||||
}
|
||||
// Now do some shufflin'.
|
||||
auto new_sites = absl::make_unique<VLogSite *[]>(num_sites_);
|
||||
for (int shuffle_num = 0; shuffle_num < num_shuffles; shuffle_num++) {
|
||||
// Each shuffle cuts the ring into three pieces and rearranges them.
|
||||
const size_t cut_a = absl::Uniform(bitgen_, size_t{0}, num_sites_);
|
||||
const size_t cut_b = absl::Uniform(bitgen_, size_t{0}, num_sites_);
|
||||
const size_t cut_c = absl::Uniform(bitgen_, size_t{0}, num_sites_);
|
||||
if (cut_a == cut_b || cut_b == cut_c || cut_a == cut_c) continue;
|
||||
// The same cuts, sorted:
|
||||
const size_t cut_1 = std::min({cut_a, cut_b, cut_c});
|
||||
const size_t cut_3 = std::max({cut_a, cut_b, cut_c});
|
||||
const size_t cut_2 = cut_a ^ cut_b ^ cut_c ^ cut_1 ^ cut_3;
|
||||
VLogSite *const tmp = sites[cut_1]->next_.load(std::memory_order_seq_cst);
|
||||
sites[cut_1]->next_.store(
|
||||
sites[cut_2]->next_.load(std::memory_order_seq_cst),
|
||||
std::memory_order_seq_cst);
|
||||
sites[cut_2]->next_.store(
|
||||
sites[cut_3]->next_.load(std::memory_order_seq_cst),
|
||||
std::memory_order_seq_cst);
|
||||
sites[cut_3]->next_.store(tmp, std::memory_order_seq_cst);
|
||||
memcpy(&new_sites[0], &sites[0], sizeof(VLogSite *) * (cut_1 + 1));
|
||||
memcpy(&new_sites[cut_1 + 1], &sites[cut_2 + 1],
|
||||
sizeof(VLogSite *) * (cut_3 - cut_2));
|
||||
memcpy(&new_sites[cut_1 + 1 + cut_3 - cut_2], &sites[cut_1 + 1],
|
||||
sizeof(VLogSite *) * (cut_2 - cut_1));
|
||||
memcpy(&new_sites[cut_3 + 1], &sites[cut_3 + 1],
|
||||
sizeof(VLogSite *) * (num_sites_ - cut_3 - 1));
|
||||
sites.swap(new_sites);
|
||||
}
|
||||
const char *last_file = nullptr;
|
||||
for (size_t i = 0; i < num_sites_; i++) {
|
||||
if (sites[i]->file_ == last_file) continue;
|
||||
last_file = sites[i]->file_;
|
||||
num_new_files_++;
|
||||
}
|
||||
absl::log_internal::SetVModuleListHeadForTestOnly(sites[0]);
|
||||
sites[num_tus - 1]->next_.store(nullptr, std::memory_order_seq_cst);
|
||||
}
|
||||
~SyntheticBinary() {
|
||||
static_assert(std::is_trivially_destructible<VLogSite>::value, "");
|
||||
absl::log_internal::SetVModuleListHeadForTestOnly(nullptr);
|
||||
}
|
||||
|
||||
size_t num_sites() const { return num_sites_; }
|
||||
size_t num_new_files() const { return num_new_files_; }
|
||||
size_t num_extra_static_data_bytes() const {
|
||||
return num_extra_static_data_bytes_;
|
||||
}
|
||||
|
||||
private:
|
||||
struct PerTU {
|
||||
container_internal::Layout<char, VLogSite, char> layout;
|
||||
std::unique_ptr<char[]> buf;
|
||||
};
|
||||
|
||||
std::mt19937 bitgen_;
|
||||
std::vector<PerTU> per_tu_data_;
|
||||
size_t num_sites_ = 0;
|
||||
size_t num_new_files_ = 0;
|
||||
size_t num_extra_static_data_bytes_ = 0;
|
||||
};
|
||||
|
||||
namespace {
|
||||
void BM_UpdateVModuleEmpty(benchmark::State& state) {
|
||||
SyntheticBinary bin(static_cast<size_t>(state.range(0)), 10 * 1024 * 1024,
|
||||
256, state.range(1));
|
||||
for (auto s : state) {
|
||||
absl::log_internal::UpdateVModule("");
|
||||
}
|
||||
state.SetItemsProcessed(static_cast<int>(bin.num_new_files()));
|
||||
}
|
||||
BENCHMARK(BM_UpdateVModuleEmpty)
|
||||
->ArgPair(100, 200)
|
||||
->ArgPair(1000, 2000)
|
||||
->ArgPair(10000, 20000);
|
||||
|
||||
void BM_UpdateVModuleShort(benchmark::State& state) {
|
||||
SyntheticBinary bin(static_cast<size_t>(state.range(0)), 10 * 1024 * 1024,
|
||||
256, state.range(1));
|
||||
for (auto s : state) {
|
||||
absl::log_internal::UpdateVModule("directory2/*=4");
|
||||
}
|
||||
state.SetItemsProcessed(static_cast<int>(bin.num_new_files()));
|
||||
}
|
||||
BENCHMARK(BM_UpdateVModuleShort)
|
||||
->ArgPair(100, 200)
|
||||
->ArgPair(1000, 2000)
|
||||
->ArgPair(10000, 20000);
|
||||
|
||||
void BM_UpdateVModuleLong(benchmark::State& state) {
|
||||
SyntheticBinary bin(static_cast<size_t>(state.range(0)), 10 * 1024 * 1024,
|
||||
256, state.range(1));
|
||||
for (auto s : state) {
|
||||
absl::log_internal::UpdateVModule(
|
||||
"d?r?c?o?y2/*=4,d?*r?*c?**o?*y1/*=2,d?*rc?**o?*y3/*=2,,"
|
||||
"d?*r?*c?**o?*1/*=1,d?*r?**o?*y1/*=2,d?*r???***y1/*=7,"
|
||||
"d?*r?**o?*y1/aaa=6");
|
||||
}
|
||||
state.SetItemsProcessed(static_cast<int>(bin.num_new_files()));
|
||||
}
|
||||
BENCHMARK(BM_UpdateVModuleLong)
|
||||
->ArgPair(100, 200)
|
||||
->ArgPair(1000, 2000)
|
||||
->ArgPair(10000, 20000);
|
||||
} // namespace
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
44
TMessagesProj/jni/voip/webrtc/absl/log/internal/voidify.h
Normal file
44
TMessagesProj/jni/voip/webrtc/absl/log/internal/voidify.h
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/internal/voidify.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This class is used to explicitly ignore values in the conditional logging
|
||||
// macros. This avoids compiler warnings like "value computed is not used" and
|
||||
// "statement has no effect".
|
||||
|
||||
#ifndef ABSL_LOG_INTERNAL_VOIDIFY_H_
|
||||
#define ABSL_LOG_INTERNAL_VOIDIFY_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
class Voidify final {
|
||||
public:
|
||||
// This has to be an operator with a precedence lower than << but higher than
|
||||
// ?:
|
||||
template <typename T>
|
||||
void operator&&(const T&) const&& {}
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_INTERNAL_VOIDIFY_H_
|
||||
369
TMessagesProj/jni/voip/webrtc/absl/log/log.h
Normal file
369
TMessagesProj/jni/voip/webrtc/absl/log/log.h
Normal file
|
|
@ -0,0 +1,369 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/log.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares a family of LOG macros.
|
||||
//
|
||||
// Basic invocation looks like this:
|
||||
//
|
||||
// LOG(INFO) << "Found " << num_cookies << " cookies";
|
||||
//
|
||||
// Most `LOG` macros take a severity level argument. The severity levels are
|
||||
// `INFO`, `WARNING`, `ERROR`, and `FATAL`. They are defined
|
||||
// in absl/base/log_severity.h.
|
||||
// * The `FATAL` severity level terminates the program with a stack trace after
|
||||
// logging its message. Error handlers registered with `RunOnFailure`
|
||||
// (process_state.h) are run, but exit handlers registered with `atexit(3)`
|
||||
// are not.
|
||||
// * The `QFATAL` pseudo-severity level is equivalent to `FATAL` but triggers
|
||||
// quieter termination messages, e.g. without a full stack trace, and skips
|
||||
// running registered error handlers.
|
||||
// * The `DFATAL` pseudo-severity level is defined as `FATAL` in debug mode and
|
||||
// as `ERROR` otherwise.
|
||||
// Some preprocessor shenanigans are used to ensure that e.g. `LOG(INFO)` has
|
||||
// the same meaning even if a local symbol or preprocessor macro named `INFO` is
|
||||
// defined. To specify a severity level using an expression instead of a
|
||||
// literal, use `LEVEL(expr)`.
|
||||
// Example:
|
||||
//
|
||||
// LOG(LEVEL(stale ? absl::LogSeverity::kWarning : absl::LogSeverity::kInfo))
|
||||
// << "Cookies are " << days << " days old";
|
||||
|
||||
// `LOG` macros evaluate to an unterminated statement. The value at the end of
|
||||
// the statement supports some chainable methods:
|
||||
//
|
||||
// * .AtLocation(absl::string_view file, int line)
|
||||
// .AtLocation(absl::SourceLocation loc)
|
||||
// Overrides the location inferred from the callsite. The string pointed to
|
||||
// by `file` must be valid until the end of the statement.
|
||||
// * .NoPrefix()
|
||||
// Omits the prefix from this line. The prefix includes metadata about the
|
||||
// logged data such as source code location and timestamp.
|
||||
// * .WithVerbosity(int verbose_level)
|
||||
// Sets the verbosity field of the logged message as if it was logged by
|
||||
// `VLOG(verbose_level)`. Unlike `VLOG`, this method does not affect
|
||||
// evaluation of the statement when the specified `verbose_level` has been
|
||||
// disabled. The only effect is on `LogSink` implementations which make use
|
||||
// of the `absl::LogSink::verbosity()` value. The value
|
||||
// `absl::LogEntry::kNoVerbosityLevel` can be specified to mark the message
|
||||
// not verbose.
|
||||
// * .WithTimestamp(absl::Time timestamp)
|
||||
// Uses the specified timestamp instead of one collected at the time of
|
||||
// execution.
|
||||
// * .WithThreadID(absl::LogEntry::tid_t tid)
|
||||
// Uses the specified thread ID instead of one collected at the time of
|
||||
// execution.
|
||||
// * .WithMetadataFrom(const absl::LogEntry &entry)
|
||||
// Copies all metadata (but no data) from the specified `absl::LogEntry`.
|
||||
// This can be used to change the severity of a message, but it has some
|
||||
// limitations:
|
||||
// * `ABSL_MIN_LOG_LEVEL` is evaluated against the severity passed into
|
||||
// `LOG` (or the implicit `FATAL` level of `CHECK`).
|
||||
// * `LOG(FATAL)` and `CHECK` terminate the process unconditionally, even if
|
||||
// the severity is changed later.
|
||||
// `.WithMetadataFrom(entry)` should almost always be used in combination
|
||||
// with `LOG(LEVEL(entry.log_severity()))`.
|
||||
// * .WithPerror()
|
||||
// Appends to the logged message a colon, a space, a textual description of
|
||||
// the current value of `errno` (as by `strerror(3)`), and the numerical
|
||||
// value of `errno`.
|
||||
// * .ToSinkAlso(absl::LogSink* sink)
|
||||
// Sends this message to `*sink` in addition to whatever other sinks it
|
||||
// would otherwise have been sent to. `sink` must not be null.
|
||||
// * .ToSinkOnly(absl::LogSink* sink)
|
||||
// Sends this message to `*sink` and no others. `sink` must not be null.
|
||||
//
|
||||
// No interfaces in this header are async-signal-safe; their use in signal
|
||||
// handlers is unsupported and may deadlock your program or eat your lunch.
|
||||
//
|
||||
// Many logging statements are inherently conditional. For example,
|
||||
// `LOG_IF(INFO, !foo)` does nothing if `foo` is true. Even seemingly
|
||||
// unconditional statements like `LOG(INFO)` might be disabled at
|
||||
// compile-time to minimize binary size or for security reasons.
|
||||
//
|
||||
// * Except for the condition in a `CHECK` or `QCHECK` statement, programs must
|
||||
// not rely on evaluation of expressions anywhere in logging statements for
|
||||
// correctness. For example, this is ok:
|
||||
//
|
||||
// CHECK((fp = fopen("config.ini", "r")) != nullptr);
|
||||
//
|
||||
// But this is probably not ok:
|
||||
//
|
||||
// LOG(INFO) << "Server status: " << StartServerAndReturnStatusString();
|
||||
//
|
||||
// The example below is bad too; the `i++` in the `LOG_IF` condition might
|
||||
// not be evaluated, resulting in an infinite loop:
|
||||
//
|
||||
// for (int i = 0; i < 1000000;)
|
||||
// LOG_IF(INFO, i++ % 1000 == 0) << "Still working...";
|
||||
//
|
||||
// * Except where otherwise noted, conditions which cause a statement not to log
|
||||
// also cause expressions not to be evaluated. Programs may rely on this for
|
||||
// performance reasons, e.g. by streaming the result of an expensive function
|
||||
// call into a `DLOG` or `LOG_EVERY_N` statement.
|
||||
// * Care has been taken to ensure that expressions are parsed by the compiler
|
||||
// even if they are never evaluated. This means that syntax errors will be
|
||||
// caught and variables will be considered used for the purposes of
|
||||
// unused-variable diagnostics. For example, this statement won't compile
|
||||
// even if `INFO`-level logging has been compiled out:
|
||||
//
|
||||
// int number_of_cakes = 40;
|
||||
// LOG(INFO) << "Number of cakes: " << number_of_cake; // Note the typo!
|
||||
//
|
||||
// Similarly, this won't produce unused-variable compiler diagnostics even
|
||||
// if `INFO`-level logging is compiled out:
|
||||
//
|
||||
// {
|
||||
// char fox_line1[] = "Hatee-hatee-hatee-ho!";
|
||||
// LOG_IF(ERROR, false) << "The fox says " << fox_line1;
|
||||
// char fox_line2[] = "A-oo-oo-oo-ooo!";
|
||||
// LOG(INFO) << "The fox also says " << fox_line2;
|
||||
// }
|
||||
//
|
||||
// This error-checking is not perfect; for example, symbols that have been
|
||||
// declared but not defined may not produce link errors if used in logging
|
||||
// statements that compile away.
|
||||
//
|
||||
// Expressions streamed into these macros are formatted using `operator<<` just
|
||||
// as they would be if streamed into a `std::ostream`, however it should be
|
||||
// noted that their actual type is unspecified.
|
||||
//
|
||||
// To implement a custom formatting operator for a type you own, there are two
|
||||
// options: `AbslStringify()` or `std::ostream& operator<<(std::ostream&, ...)`.
|
||||
// It is recommended that users make their types loggable through
|
||||
// `AbslStringify()` as it is a universal stringification extension that also
|
||||
// enables `absl::StrFormat` and `absl::StrCat` support. If both
|
||||
// `AbslStringify()` and `std::ostream& operator<<(std::ostream&, ...)` are
|
||||
// defined, `AbslStringify()` will be used.
|
||||
//
|
||||
// To use the `AbslStringify()` API, define a friend function template in your
|
||||
// type's namespace with the following signature:
|
||||
//
|
||||
// template <typename Sink>
|
||||
// void AbslStringify(Sink& sink, const UserDefinedType& value);
|
||||
//
|
||||
// `Sink` has the same interface as `absl::FormatSink`, but without
|
||||
// `PutPaddedString()`.
|
||||
//
|
||||
// Example:
|
||||
//
|
||||
// struct Point {
|
||||
// template <typename Sink>
|
||||
// friend void AbslStringify(Sink& sink, const Point& p) {
|
||||
// absl::Format(&sink, "(%v, %v)", p.x, p.y);
|
||||
// }
|
||||
//
|
||||
// int x;
|
||||
// int y;
|
||||
// };
|
||||
//
|
||||
// To use `std::ostream& operator<<(std::ostream&, ...)`, define
|
||||
// `std::ostream& operator<<(std::ostream&, ...)` in your type's namespace (for
|
||||
// ADL) just as you would to stream it to `std::cout`.
|
||||
//
|
||||
// Currently `AbslStringify()` ignores output manipulators but this is not
|
||||
// guaranteed behavior and may be subject to change in the future. If you would
|
||||
// like guaranteed behavior regarding output manipulators, please use
|
||||
// `std::ostream& operator<<(std::ostream&, ...)` to make custom types loggable
|
||||
// instead.
|
||||
//
|
||||
// Those macros that support streaming honor output manipulators and `fmtflag`
|
||||
// changes that output data (e.g. `std::ends`) or control formatting of data
|
||||
// (e.g. `std::hex` and `std::fixed`), however flushing such a stream is
|
||||
// ignored. The message produced by a log statement is sent to registered
|
||||
// `absl::LogSink` instances at the end of the statement; those sinks are
|
||||
// responsible for their own flushing (e.g. to disk) semantics.
|
||||
//
|
||||
// Flag settings are not carried over from one `LOG` statement to the next; this
|
||||
// is a bit different than e.g. `std::cout`:
|
||||
//
|
||||
// LOG(INFO) << std::hex << 0xdeadbeef; // logs "0xdeadbeef"
|
||||
// LOG(INFO) << 0xdeadbeef; // logs "3735928559"
|
||||
|
||||
#ifndef ABSL_LOG_LOG_H_
|
||||
#define ABSL_LOG_LOG_H_
|
||||
|
||||
#include "absl/log/internal/log_impl.h"
|
||||
|
||||
// LOG()
|
||||
//
|
||||
// `LOG` takes a single argument which is a severity level. Data streamed in
|
||||
// comprise the logged message.
|
||||
// Example:
|
||||
//
|
||||
// LOG(INFO) << "Found " << num_cookies << " cookies";
|
||||
#define LOG(severity) ABSL_LOG_INTERNAL_LOG_IMPL(_##severity)
|
||||
|
||||
// PLOG()
|
||||
//
|
||||
// `PLOG` behaves like `LOG` except that a description of the current state of
|
||||
// `errno` is appended to the streamed message.
|
||||
#define PLOG(severity) ABSL_LOG_INTERNAL_PLOG_IMPL(_##severity)
|
||||
|
||||
// DLOG()
|
||||
//
|
||||
// `DLOG` behaves like `LOG` in debug mode (i.e. `#ifndef NDEBUG`). Otherwise
|
||||
// it compiles away and does nothing. Note that `DLOG(FATAL)` does not
|
||||
// terminate the program if `NDEBUG` is defined.
|
||||
#define DLOG(severity) ABSL_LOG_INTERNAL_DLOG_IMPL(_##severity)
|
||||
|
||||
// `VLOG` uses numeric levels to provide verbose logging that can configured at
|
||||
// runtime, including at a per-module level. `VLOG` statements are logged at
|
||||
// `INFO` severity if they are logged at all; the numeric levels are on a
|
||||
// different scale than the proper severity levels. Positive levels are
|
||||
// disabled by default. Negative levels should not be used.
|
||||
// Example:
|
||||
//
|
||||
// VLOG(1) << "I print when you run the program with --v=1 or higher";
|
||||
// VLOG(2) << "I print when you run the program with --v=2 or higher";
|
||||
//
|
||||
// See vlog_is_on.h for further documentation, including the usage of the
|
||||
// --vmodule flag to log at different levels in different source files.
|
||||
//
|
||||
// `VLOG` does not produce any output when verbose logging is not enabled.
|
||||
// However, simply testing whether verbose logging is enabled can be expensive.
|
||||
// If you don't intend to enable verbose logging in non-debug builds, consider
|
||||
// using `DVLOG` instead.
|
||||
#define VLOG(severity) ABSL_LOG_INTERNAL_VLOG_IMPL(severity)
|
||||
|
||||
// `DVLOG` behaves like `VLOG` in debug mode (i.e. `#ifndef NDEBUG`).
|
||||
// Otherwise, it compiles away and does nothing.
|
||||
#define DVLOG(severity) ABSL_LOG_INTERNAL_DVLOG_IMPL(severity)
|
||||
|
||||
// `LOG_IF` and friends add a second argument which specifies a condition. If
|
||||
// the condition is false, nothing is logged.
|
||||
// Example:
|
||||
//
|
||||
// LOG_IF(INFO, num_cookies > 10) << "Got lots of cookies";
|
||||
//
|
||||
// There is no `VLOG_IF` because the order of evaluation of the arguments is
|
||||
// ambiguous and the alternate spelling with an `if`-statement is trivial.
|
||||
#define LOG_IF(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_IMPL(_##severity, condition)
|
||||
#define PLOG_IF(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_IMPL(_##severity, condition)
|
||||
#define DLOG_IF(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_IMPL(_##severity, condition)
|
||||
|
||||
// LOG_EVERY_N
|
||||
// LOG_FIRST_N
|
||||
// LOG_EVERY_POW_2
|
||||
// LOG_EVERY_N_SEC
|
||||
//
|
||||
// These "stateful" macros log conditionally based on a hidden counter or timer.
|
||||
// When the condition is false and no logging is done, streamed operands aren't
|
||||
// evaluated either. Each instance has its own state (i.e. counter, timer)
|
||||
// that's independent of other instances of the macros. The macros in this
|
||||
// family are thread-safe in the sense that they are meant to be called
|
||||
// concurrently and will not invoke undefined behavior, however their
|
||||
// implementation prioritizes efficiency over exactness and may occasionally log
|
||||
// more or less often than specified.
|
||||
//
|
||||
// * `LOG_EVERY_N` logs the first time and once every `n` times thereafter.
|
||||
// * `LOG_FIRST_N` logs the first `n` times and then stops.
|
||||
// * `LOG_EVERY_POW_2` logs the first, second, fourth, eighth, etc. times.
|
||||
// * `LOG_EVERY_N_SEC` logs the first time and no more than once every `n`
|
||||
// seconds thereafter. `n` is passed as a floating point value.
|
||||
//
|
||||
// The `LOG_IF`... variations with an extra condition evaluate the specified
|
||||
// condition first and short-circuit if it is false. For example, an evaluation
|
||||
// of `LOG_IF_FIRST_N` does not count against the first `n` if the specified
|
||||
// condition is false. Stateful `VLOG`... variations likewise short-circuit
|
||||
// if `VLOG` is disabled.
|
||||
//
|
||||
// An approximate count of the number of times a particular instance's stateful
|
||||
// condition has been evaluated (i.e. excluding those where a specified `LOG_IF`
|
||||
// condition was false) can be included in the logged message by streaming the
|
||||
// symbol `COUNTER`.
|
||||
//
|
||||
// The `n` parameter need not be a constant. Conditional logging following a
|
||||
// change to `n` isn't fully specified, but it should converge on the new value
|
||||
// within roughly `max(old_n, new_n)` evaluations or seconds.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// LOG_EVERY_N(WARNING, 1000) << "Got a packet with a bad CRC (" << COUNTER
|
||||
// << " total)";
|
||||
//
|
||||
// LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far";
|
||||
//
|
||||
// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER
|
||||
// << "th big cookie";
|
||||
#define LOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n)
|
||||
#define LOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n)
|
||||
#define LOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity)
|
||||
#define LOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_LOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
|
||||
|
||||
#define PLOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_EVERY_N_IMPL(_##severity, n)
|
||||
#define PLOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_FIRST_N_IMPL(_##severity, n)
|
||||
#define PLOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_PLOG_EVERY_POW_2_IMPL(_##severity)
|
||||
#define PLOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_PLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
|
||||
|
||||
#define DLOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_EVERY_N_IMPL(_##severity, n)
|
||||
#define DLOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_FIRST_N_IMPL(_##severity, n)
|
||||
#define DLOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_DLOG_EVERY_POW_2_IMPL(_##severity)
|
||||
#define DLOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_DLOG_EVERY_N_SEC_IMPL(_##severity, n_seconds)
|
||||
|
||||
#define VLOG_EVERY_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_VLOG_EVERY_N_IMPL(severity, n)
|
||||
#define VLOG_FIRST_N(severity, n) \
|
||||
ABSL_LOG_INTERNAL_VLOG_FIRST_N_IMPL(severity, n)
|
||||
#define VLOG_EVERY_POW_2(severity) \
|
||||
ABSL_LOG_INTERNAL_VLOG_EVERY_POW_2_IMPL(severity)
|
||||
#define VLOG_EVERY_N_SEC(severity, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_VLOG_EVERY_N_SEC_IMPL(severity, n_seconds)
|
||||
|
||||
#define LOG_IF_EVERY_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_IMPL(_##severity, condition, n)
|
||||
#define LOG_IF_FIRST_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_FIRST_N_IMPL(_##severity, condition, n)
|
||||
#define LOG_IF_EVERY_POW_2(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
|
||||
#define LOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_LOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
|
||||
|
||||
#define PLOG_IF_EVERY_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
|
||||
#define PLOG_IF_FIRST_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
|
||||
#define PLOG_IF_EVERY_POW_2(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
|
||||
#define PLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_PLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
|
||||
|
||||
#define DLOG_IF_EVERY_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_IMPL(_##severity, condition, n)
|
||||
#define DLOG_IF_FIRST_N(severity, condition, n) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_FIRST_N_IMPL(_##severity, condition, n)
|
||||
#define DLOG_IF_EVERY_POW_2(severity, condition) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_EVERY_POW_2_IMPL(_##severity, condition)
|
||||
#define DLOG_IF_EVERY_N_SEC(severity, condition, n_seconds) \
|
||||
ABSL_LOG_INTERNAL_DLOG_IF_EVERY_N_SEC_IMPL(_##severity, condition, n_seconds)
|
||||
|
||||
#endif // ABSL_LOG_LOG_H_
|
||||
22
TMessagesProj/jni/voip/webrtc/absl/log/log_basic_test.cc
Normal file
22
TMessagesProj/jni/voip/webrtc/absl/log/log_basic_test.cc
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/log.h"
|
||||
|
||||
#define ABSL_TEST_LOG LOG
|
||||
#define ABSL_TEST_DLOG DLOG
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/log/log_basic_test_impl.inc"
|
||||
609
TMessagesProj/jni/voip/webrtc/absl/log/log_basic_test_impl.inc
Normal file
609
TMessagesProj/jni/voip/webrtc/absl/log/log_basic_test_impl.inc
Normal file
|
|
@ -0,0 +1,609 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// The testcases in this file are expected to pass or be skipped with any value
|
||||
// of ABSL_MIN_LOG_LEVEL
|
||||
|
||||
#ifndef ABSL_LOG_LOG_BASIC_TEST_IMPL_H_
|
||||
#define ABSL_LOG_LOG_BASIC_TEST_IMPL_H_
|
||||
|
||||
// Verify that both sets of macros behave identically by parameterizing the
|
||||
// entire test file.
|
||||
#ifndef ABSL_TEST_LOG
|
||||
#error ABSL_TEST_LOG must be defined for these tests to work.
|
||||
#endif
|
||||
|
||||
#ifndef ABSL_TEST_DLOG
|
||||
#error ABSL_TEST_DLOG must be defined for these tests to work.
|
||||
#endif
|
||||
|
||||
#include <cerrno>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/internal/sysinfo.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/globals.h"
|
||||
#include "absl/log/internal/test_actions.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
|
||||
namespace absl_log_internal {
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
using ::absl::log_internal::DeathTestExpectedLogging;
|
||||
using ::absl::log_internal::DeathTestUnexpectedLogging;
|
||||
using ::absl::log_internal::DeathTestValidateExpectations;
|
||||
using ::absl::log_internal::DiedOfFatal;
|
||||
using ::absl::log_internal::DiedOfQFatal;
|
||||
#endif
|
||||
using ::absl::log_internal::InMatchWindow;
|
||||
using ::absl::log_internal::LoggingEnabledAt;
|
||||
using ::absl::log_internal::LogSeverity;
|
||||
using ::absl::log_internal::Prefix;
|
||||
using ::absl::log_internal::SourceBasename;
|
||||
using ::absl::log_internal::SourceFilename;
|
||||
using ::absl::log_internal::SourceLine;
|
||||
using ::absl::log_internal::Stacktrace;
|
||||
using ::absl::log_internal::TextMessage;
|
||||
using ::absl::log_internal::ThreadID;
|
||||
using ::absl::log_internal::Timestamp;
|
||||
using ::absl::log_internal::Verbosity;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::Eq;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsTrue;
|
||||
|
||||
class BasicLogTest : public testing::TestWithParam<absl::LogSeverityAtLeast> {};
|
||||
|
||||
std::string ThresholdName(
|
||||
testing::TestParamInfo<absl::LogSeverityAtLeast> severity) {
|
||||
std::stringstream ostr;
|
||||
ostr << severity.param;
|
||||
return ostr.str().substr(
|
||||
severity.param == absl::LogSeverityAtLeast::kInfinity ? 0 : 2);
|
||||
}
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(WithParam, BasicLogTest,
|
||||
testing::Values(absl::LogSeverityAtLeast::kInfo,
|
||||
absl::LogSeverityAtLeast::kWarning,
|
||||
absl::LogSeverityAtLeast::kError,
|
||||
absl::LogSeverityAtLeast::kFatal,
|
||||
absl::LogSeverityAtLeast::kInfinity),
|
||||
ThresholdName);
|
||||
|
||||
TEST_P(BasicLogTest, Info) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(INFO) << "hello world"; };
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kInfo)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kInfo)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::INFO), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
}
|
||||
|
||||
TEST_P(BasicLogTest, Warning) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(WARNING) << "hello world"; };
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kWarning)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kWarning)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::WARNING), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
}
|
||||
|
||||
TEST_P(BasicLogTest, Error) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(ERROR) << "hello world"; };
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kError)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kError)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
using BasicLogDeathTest = BasicLogTest;
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(WithParam, BasicLogDeathTest,
|
||||
testing::Values(absl::LogSeverityAtLeast::kInfo,
|
||||
absl::LogSeverityAtLeast::kFatal,
|
||||
absl::LogSeverityAtLeast::kInfinity),
|
||||
ThresholdName);
|
||||
|
||||
TEST_P(BasicLogDeathTest, Fatal) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(FATAL) << "hello world"; };
|
||||
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink(
|
||||
absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
::testing::InSequence s;
|
||||
|
||||
// Note the logic in DeathTestValidateExpectations() caters for the case
|
||||
// of logging being disabled at FATAL level.
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
|
||||
// The first call without the stack trace.
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
// The second call with the stack trace.
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(Not(IsEmpty())))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
TEST_P(BasicLogDeathTest, QFatal) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(QFATAL) << "hello world"; };
|
||||
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink(
|
||||
absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
},
|
||||
DiedOfQFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
TEST_P(BasicLogTest, DFatal) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(DFATAL) << "hello world"; };
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kError)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kError)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
}
|
||||
|
||||
#elif GTEST_HAS_DEATH_TEST
|
||||
TEST_P(BasicLogDeathTest, DFatal) {
|
||||
// TODO(b/242568884): re-enable once bug is fixed.
|
||||
// absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [] { ABSL_TEST_LOG(DFATAL) << "hello world"; };
|
||||
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink(
|
||||
absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
::testing::InSequence s;
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
|
||||
// The first call without the stack trace.
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
// The second call with the stack trace.
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(Not(IsEmpty())))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef NDEBUG
|
||||
TEST_P(BasicLogTest, DFatalIsCancellable) {
|
||||
// LOG(DFATAL) does not die when DFATAL death is disabled.
|
||||
absl::log_internal::SetExitOnDFatal(false);
|
||||
ABSL_TEST_LOG(DFATAL) << "hello world";
|
||||
absl::log_internal::SetExitOnDFatal(true);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST_P(BasicLogDeathTest, DLogFatalIsNotCancellable) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::log_internal::SetExitOnDFatal(false);
|
||||
ABSL_TEST_DLOG(FATAL) << "hello world";
|
||||
absl::log_internal::SetExitOnDFatal(true);
|
||||
},
|
||||
DiedOfFatal, "");
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
TEST_P(BasicLogTest, Level) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
for (auto severity : {absl::LogSeverity::kInfo, absl::LogSeverity::kWarning,
|
||||
absl::LogSeverity::kError}) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
const int log_line = __LINE__ + 2;
|
||||
auto do_log = [severity] {
|
||||
ABSL_TEST_LOG(LEVEL(severity)) << "hello world";
|
||||
};
|
||||
|
||||
if (LoggingEnabledAt(severity)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(severity)), Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(severity == absl::LogSeverity::kInfo ? logging::proto::INFO
|
||||
: severity == absl::LogSeverity::kWarning
|
||||
? logging::proto::WARNING
|
||||
: severity == absl::LogSeverity::kError
|
||||
? logging::proto::ERROR
|
||||
: 0),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
}
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
}
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST_P(BasicLogDeathTest, Level) {
|
||||
// TODO(b/242568884): re-enable once bug is fixed.
|
||||
// absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
// Ensure that `severity` is not a compile-time constant to prove that
|
||||
// `LOG(LEVEL(severity))` works regardless:
|
||||
auto volatile severity = absl::LogSeverity::kFatal;
|
||||
|
||||
const int log_line = __LINE__ + 1;
|
||||
auto do_log = [severity] { ABSL_TEST_LOG(LEVEL(severity)) << "hello world"; };
|
||||
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink(
|
||||
absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
::testing::InSequence s;
|
||||
|
||||
if (LoggingEnabledAt(absl::LogSeverity::kFatal)) {
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(IsEmpty()))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq(__FILE__)),
|
||||
SourceBasename(Eq("log_basic_test_impl.inc")),
|
||||
SourceLine(Eq(log_line)), Prefix(IsTrue()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("hello world")),
|
||||
Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq(__FILE__), Eq(log_line), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithLiteral(Eq("hello world"))))),
|
||||
Stacktrace(Not(IsEmpty())))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
}
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST_P(BasicLogTest, LevelClampsNegativeValues) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
if (!LoggingEnabledAt(absl::LogSeverity::kInfo)) {
|
||||
GTEST_SKIP() << "This test cases required INFO log to be enabled";
|
||||
return;
|
||||
}
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(LogSeverity(Eq(absl::LogSeverity::kInfo))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
ABSL_TEST_LOG(LEVEL(-1)) << "hello world";
|
||||
}
|
||||
|
||||
TEST_P(BasicLogTest, LevelClampsLargeValues) {
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(GetParam());
|
||||
|
||||
if (!LoggingEnabledAt(absl::LogSeverity::kError)) {
|
||||
GTEST_SKIP() << "This test cases required ERROR log to be enabled";
|
||||
return;
|
||||
}
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(LogSeverity(Eq(absl::LogSeverity::kError))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
ABSL_TEST_LOG(LEVEL(static_cast<int>(absl::LogSeverity::kFatal) + 1))
|
||||
<< "hello world";
|
||||
}
|
||||
|
||||
TEST(ErrnoPreservationTest, InSeverityExpression) {
|
||||
errno = 77;
|
||||
int saved_errno;
|
||||
ABSL_TEST_LOG(LEVEL((saved_errno = errno, absl::LogSeverity::kInfo)));
|
||||
EXPECT_THAT(saved_errno, Eq(77));
|
||||
}
|
||||
|
||||
TEST(ErrnoPreservationTest, InStreamedExpression) {
|
||||
if (!LoggingEnabledAt(absl::LogSeverity::kInfo)) {
|
||||
GTEST_SKIP() << "This test cases required INFO log to be enabled";
|
||||
return;
|
||||
}
|
||||
|
||||
errno = 77;
|
||||
int saved_errno = 0;
|
||||
ABSL_TEST_LOG(INFO) << (saved_errno = errno, "hello world");
|
||||
EXPECT_THAT(saved_errno, Eq(77));
|
||||
}
|
||||
|
||||
TEST(ErrnoPreservationTest, AfterStatement) {
|
||||
errno = 77;
|
||||
ABSL_TEST_LOG(INFO);
|
||||
const int saved_errno = errno;
|
||||
EXPECT_THAT(saved_errno, Eq(77));
|
||||
}
|
||||
|
||||
// Tests that using a variable/parameter in a logging statement suppresses
|
||||
// unused-variable/parameter warnings.
|
||||
// -----------------------------------------------------------------------
|
||||
class UnusedVariableWarningCompileTest {
|
||||
// These four don't prove anything unless `ABSL_MIN_LOG_LEVEL` is greater than
|
||||
// `kInfo`.
|
||||
static void LoggedVariable() {
|
||||
const int x = 0;
|
||||
ABSL_TEST_LOG(INFO) << x;
|
||||
}
|
||||
static void LoggedParameter(const int x) { ABSL_TEST_LOG(INFO) << x; }
|
||||
static void SeverityVariable() {
|
||||
const int x = 0;
|
||||
ABSL_TEST_LOG(LEVEL(x)) << "hello world";
|
||||
}
|
||||
static void SeverityParameter(const int x) {
|
||||
ABSL_TEST_LOG(LEVEL(x)) << "hello world";
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace absl_log_internal
|
||||
|
||||
#endif // ABSL_LOG_LOG_BASIC_TEST_IMPL_H_
|
||||
164
TMessagesProj/jni/voip/webrtc/absl/log/log_benchmark.cc
Normal file
164
TMessagesProj/jni/voip/webrtc/absl/log/log_benchmark.cc
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/flags.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/log/log_sink_registry.h"
|
||||
#include "absl/log/vlog_is_on.h"
|
||||
#include "benchmark/benchmark.h"
|
||||
|
||||
namespace {
|
||||
|
||||
class NullLogSink : public absl::LogSink {
|
||||
public:
|
||||
NullLogSink() { absl::AddLogSink(this); }
|
||||
|
||||
~NullLogSink() override { absl::RemoveLogSink(this); }
|
||||
|
||||
void Send(const absl::LogEntry&) override {}
|
||||
};
|
||||
|
||||
constexpr int x = -1;
|
||||
|
||||
void BM_SuccessfulBinaryCheck(benchmark::State& state) {
|
||||
int n = 0;
|
||||
while (state.KeepRunningBatch(8)) {
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
CHECK_GE(n, x);
|
||||
++n;
|
||||
}
|
||||
benchmark::DoNotOptimize(n);
|
||||
}
|
||||
BENCHMARK(BM_SuccessfulBinaryCheck);
|
||||
|
||||
static void BM_SuccessfulUnaryCheck(benchmark::State& state) {
|
||||
int n = 0;
|
||||
while (state.KeepRunningBatch(8)) {
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
CHECK(n >= x);
|
||||
++n;
|
||||
}
|
||||
benchmark::DoNotOptimize(n);
|
||||
}
|
||||
BENCHMARK(BM_SuccessfulUnaryCheck);
|
||||
|
||||
static void BM_DisabledLogOverhead(benchmark::State& state) {
|
||||
absl::ScopedStderrThreshold disable_stderr_logging(
|
||||
absl::LogSeverityAtLeast::kInfinity);
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(
|
||||
absl::LogSeverityAtLeast::kInfinity);
|
||||
for (auto _ : state) {
|
||||
LOG(INFO);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_DisabledLogOverhead);
|
||||
|
||||
static void BM_EnabledLogOverhead(benchmark::State& state) {
|
||||
absl::ScopedStderrThreshold stderr_logging(
|
||||
absl::LogSeverityAtLeast::kInfinity);
|
||||
absl::log_internal::ScopedMinLogLevel scoped_min_log_level(
|
||||
absl::LogSeverityAtLeast::kInfo);
|
||||
ABSL_ATTRIBUTE_UNUSED NullLogSink null_sink;
|
||||
for (auto _ : state) {
|
||||
LOG(INFO);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_EnabledLogOverhead);
|
||||
|
||||
static void BM_VlogIsOnOverhead(benchmark::State& state) {
|
||||
// It would make sense to do this only when state.thread_index == 0,
|
||||
// but thread_index is an int on some platforms (e.g. Android) and a
|
||||
// function returning an int on others. So we just do it on all threads.
|
||||
// TODO(b/152609127): set only if thread_index == 0.
|
||||
absl::SetFlag(&FLAGS_v, 0);
|
||||
|
||||
while (state.KeepRunningBatch(10)) {
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 1
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 2
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 3
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 4
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 5
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 6
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 7
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 8
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 9
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(0)); // 10
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_VlogIsOnOverhead)->ThreadRange(1, 64);
|
||||
|
||||
static void BM_VlogIsNotOnOverhead(benchmark::State& state) {
|
||||
// It would make sense to do this only when state.thread_index == 0,
|
||||
// but thread_index is an int on some platforms (e.g. Android) and a
|
||||
// function returning an int on others. So we just do it on all threads.
|
||||
// TODO(b/152609127): set only if thread_index == 0.
|
||||
absl::SetFlag(&FLAGS_v, 0);
|
||||
|
||||
while (state.KeepRunningBatch(10)) {
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 1
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 2
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 3
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 4
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 5
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 6
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 7
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 8
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 9
|
||||
benchmark::DoNotOptimize(VLOG_IS_ON(1)); // 10
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_VlogIsNotOnOverhead)->ThreadRange(1, 64);
|
||||
|
||||
static void BM_LogEveryNOverhead(benchmark::State& state) {
|
||||
absl::ScopedStderrThreshold disable_stderr_logging(
|
||||
absl::LogSeverityAtLeast::kInfinity);
|
||||
absl::SetMinLogLevel(absl::LogSeverityAtLeast::kInfinity);
|
||||
ABSL_ATTRIBUTE_UNUSED NullLogSink null_sink;
|
||||
|
||||
while (state.KeepRunningBatch(10)) {
|
||||
LOG_EVERY_N_SEC(INFO, 10);
|
||||
LOG_EVERY_N_SEC(INFO, 20);
|
||||
LOG_EVERY_N_SEC(INFO, 30);
|
||||
LOG_EVERY_N_SEC(INFO, 40);
|
||||
LOG_EVERY_N_SEC(INFO, 50);
|
||||
LOG_EVERY_N_SEC(INFO, 60);
|
||||
LOG_EVERY_N_SEC(INFO, 70);
|
||||
LOG_EVERY_N_SEC(INFO, 80);
|
||||
LOG_EVERY_N_SEC(INFO, 90);
|
||||
LOG_EVERY_N_SEC(INFO, 100);
|
||||
}
|
||||
}
|
||||
BENCHMARK(BM_LogEveryNOverhead)->ThreadRange(1, 64);
|
||||
|
||||
} // namespace
|
||||
|
||||
41
TMessagesProj/jni/voip/webrtc/absl/log/log_entry.cc
Normal file
41
TMessagesProj/jni/voip/webrtc/absl/log/log_entry.cc
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/log_entry.h"
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
#ifdef ABSL_INTERNAL_NEED_REDUNDANT_CONSTEXPR_DECL
|
||||
constexpr int LogEntry::kNoVerbosityLevel;
|
||||
constexpr int LogEntry::kNoVerboseLevel;
|
||||
#endif
|
||||
|
||||
// https://github.com/abseil/abseil-cpp/issues/1465
|
||||
// CMake builds on Apple platforms error when libraries are empty.
|
||||
// Our CMake configuration can avoid this error on header-only libraries,
|
||||
// but since this library is conditionally empty, including a single
|
||||
// variable is an easy workaround.
|
||||
#ifdef __APPLE__
|
||||
namespace log_internal {
|
||||
extern const char kAvoidEmptyLogEntryLibraryWarning;
|
||||
const char kAvoidEmptyLogEntryLibraryWarning = 0;
|
||||
} // namespace log_internal
|
||||
#endif // __APPLE__
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
221
TMessagesProj/jni/voip/webrtc/absl/log/log_entry.h
Normal file
221
TMessagesProj/jni/voip/webrtc/absl/log/log_entry.h
Normal file
|
|
@ -0,0 +1,221 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/log_entry.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares `class absl::LogEntry`, which represents a log record as
|
||||
// passed to `LogSink::Send`. Data returned by pointer or by reference or by
|
||||
// `absl::string_view` must be copied if they are needed after the lifetime of
|
||||
// the `absl::LogEntry`.
|
||||
|
||||
#ifndef ABSL_LOG_LOG_ENTRY_H_
|
||||
#define ABSL_LOG_LOG_ENTRY_H_
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/config.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
namespace log_internal {
|
||||
// Test only friend.
|
||||
class LogEntryTestPeer;
|
||||
class LogMessage;
|
||||
} // namespace log_internal
|
||||
|
||||
// LogEntry
|
||||
//
|
||||
// Represents a single entry in a log, i.e., one `LOG` statement or failed
|
||||
// `CHECK`.
|
||||
//
|
||||
// `LogEntry` is thread-compatible.
|
||||
class LogEntry final {
|
||||
public:
|
||||
using tid_t = log_internal::Tid;
|
||||
|
||||
// For non-verbose log entries, `verbosity()` returns `kNoVerbosityLevel`.
|
||||
static constexpr int kNoVerbosityLevel = -1;
|
||||
static constexpr int kNoVerboseLevel = -1; // TO BE removed
|
||||
|
||||
// Pass `LogEntry` by reference, and do not store it as its state does not
|
||||
// outlive the call to `LogSink::Send()`.
|
||||
LogEntry(const LogEntry&) = delete;
|
||||
LogEntry& operator=(const LogEntry&) = delete;
|
||||
|
||||
// Source file and line where the log message occurred. Taken from `__FILE__`
|
||||
// and `__LINE__` unless overridden by `LOG(...).AtLocation(...)`.
|
||||
//
|
||||
// Take special care not to use the values returned by `source_filename()` and
|
||||
// `source_basename()` after the lifetime of the entry. This is always
|
||||
// incorrect, but it will often work in practice because they usually point
|
||||
// into a statically allocated character array obtained from `__FILE__`.
|
||||
// Statements like `LOG(INFO).AtLocation(std::string(...), ...)` will expose
|
||||
// the bug. If you need the data later, you must copy them.
|
||||
absl::string_view source_filename() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return full_filename_;
|
||||
}
|
||||
absl::string_view source_basename() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return base_filename_;
|
||||
}
|
||||
int source_line() const { return line_; }
|
||||
|
||||
// LogEntry::prefix()
|
||||
//
|
||||
// True unless the metadata prefix was suppressed once by
|
||||
// `LOG(...).NoPrefix()` or globally by `absl::EnableLogPrefix(false)`.
|
||||
// Implies `text_message_with_prefix() == text_message()`.
|
||||
bool prefix() const { return prefix_; }
|
||||
|
||||
// LogEntry::log_severity()
|
||||
//
|
||||
// Returns this entry's severity. For `LOG`, taken from the first argument;
|
||||
// for `CHECK`, always `absl::LogSeverity::kFatal`.
|
||||
absl::LogSeverity log_severity() const { return severity_; }
|
||||
|
||||
// LogEntry::verbosity()
|
||||
//
|
||||
// Returns this entry's verbosity, or `kNoVerbosityLevel` for a non-verbose
|
||||
// entry. Taken from the argument to `VLOG` or from
|
||||
// `LOG(...).WithVerbosity(...)`.
|
||||
int verbosity() const { return verbose_level_; }
|
||||
|
||||
// LogEntry::timestamp()
|
||||
//
|
||||
// Returns the time at which this entry was written. Captured during
|
||||
// evaluation of `LOG`, but can be overridden by
|
||||
// `LOG(...).WithTimestamp(...)`.
|
||||
//
|
||||
// Take care not to rely on timestamps increasing monotonically, or even to
|
||||
// rely on timestamps having any particular relationship with reality (since
|
||||
// they can be overridden).
|
||||
absl::Time timestamp() const { return timestamp_; }
|
||||
|
||||
// LogEntry::tid()
|
||||
//
|
||||
// Returns the ID of the thread that wrote this entry. Captured during
|
||||
// evaluation of `LOG`, but can be overridden by `LOG(...).WithThreadID(...)`.
|
||||
//
|
||||
// Take care not to *rely* on reported thread IDs as they can be overridden as
|
||||
// specified above.
|
||||
tid_t tid() const { return tid_; }
|
||||
|
||||
// Text-formatted version of the log message. An underlying buffer holds
|
||||
// these contiguous data:
|
||||
//
|
||||
// * A prefix formed by formatting metadata (timestamp, filename, line number,
|
||||
// etc.)
|
||||
// The prefix may be empty - see `LogEntry::prefix()` - and may rarely be
|
||||
// truncated if the metadata are very long.
|
||||
// * The streamed data
|
||||
// The data may be empty if nothing was streamed, or may be truncated to fit
|
||||
// the buffer.
|
||||
// * A newline
|
||||
// * A nul terminator
|
||||
//
|
||||
// The newline and nul terminator will be present even if the prefix and/or
|
||||
// data are truncated.
|
||||
//
|
||||
// These methods give access to the most commonly useful substrings of the
|
||||
// buffer's contents. Other combinations can be obtained with substring
|
||||
// arithmetic.
|
||||
//
|
||||
// The buffer does not outlive the entry; if you need the data later, you must
|
||||
// copy them.
|
||||
absl::string_view text_message_with_prefix_and_newline() const
|
||||
ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return absl::string_view(
|
||||
text_message_with_prefix_and_newline_and_nul_.data(),
|
||||
text_message_with_prefix_and_newline_and_nul_.size() - 1);
|
||||
}
|
||||
absl::string_view text_message_with_prefix() const
|
||||
ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return absl::string_view(
|
||||
text_message_with_prefix_and_newline_and_nul_.data(),
|
||||
text_message_with_prefix_and_newline_and_nul_.size() - 2);
|
||||
}
|
||||
absl::string_view text_message_with_newline() const
|
||||
ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return absl::string_view(
|
||||
text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_,
|
||||
text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 1);
|
||||
}
|
||||
absl::string_view text_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return absl::string_view(
|
||||
text_message_with_prefix_and_newline_and_nul_.data() + prefix_len_,
|
||||
text_message_with_prefix_and_newline_and_nul_.size() - prefix_len_ - 2);
|
||||
}
|
||||
const char* text_message_with_prefix_and_newline_c_str() const
|
||||
ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return text_message_with_prefix_and_newline_and_nul_.data();
|
||||
}
|
||||
|
||||
// Returns a serialized protobuf holding the operands streamed into this
|
||||
// log message. The message definition is not yet published.
|
||||
//
|
||||
// The buffer does not outlive the entry; if you need the data later, you must
|
||||
// copy them.
|
||||
absl::string_view encoded_message() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return encoding_;
|
||||
}
|
||||
|
||||
// LogEntry::stacktrace()
|
||||
//
|
||||
// Optional stacktrace, e.g. for `FATAL` logs and failed `CHECK`s.
|
||||
//
|
||||
// Fatal entries are dispatched to each sink twice: first with all data and
|
||||
// metadata but no stacktrace, and then with the stacktrace. This is done
|
||||
// because stacktrace collection is sometimes slow and fallible, and it's
|
||||
// critical to log enough information to diagnose the failure even if the
|
||||
// stacktrace collection hangs.
|
||||
//
|
||||
// The buffer does not outlive the entry; if you need the data later, you must
|
||||
// copy them.
|
||||
absl::string_view stacktrace() const ABSL_ATTRIBUTE_LIFETIME_BOUND {
|
||||
return stacktrace_;
|
||||
}
|
||||
|
||||
private:
|
||||
LogEntry() = default;
|
||||
|
||||
absl::string_view full_filename_;
|
||||
absl::string_view base_filename_;
|
||||
int line_;
|
||||
bool prefix_;
|
||||
absl::LogSeverity severity_;
|
||||
int verbose_level_; // >=0 for `VLOG`, etc.; otherwise `kNoVerbosityLevel`.
|
||||
absl::Time timestamp_;
|
||||
tid_t tid_;
|
||||
absl::Span<const char> text_message_with_prefix_and_newline_and_nul_;
|
||||
size_t prefix_len_;
|
||||
absl::string_view encoding_;
|
||||
std::string stacktrace_;
|
||||
|
||||
friend class log_internal::LogEntryTestPeer;
|
||||
friend class log_internal::LogMessage;
|
||||
};
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_LOG_ENTRY_H_
|
||||
468
TMessagesProj/jni/voip/webrtc/absl/log/log_entry_test.cc
Normal file
468
TMessagesProj/jni/voip/webrtc/absl/log/log_entry_test.cc
Normal file
|
|
@ -0,0 +1,468 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/log_entry.h"
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
#include <string>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/append_truncated.h"
|
||||
#include "absl/log/internal/log_format.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/strings/numbers.h"
|
||||
#include "absl/strings/str_split.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/civil_time.h"
|
||||
#include "absl/time/time.h"
|
||||
#include "absl/types/span.h"
|
||||
|
||||
namespace {
|
||||
using ::absl::log_internal::LogEntryTestPeer;
|
||||
using ::testing::Eq;
|
||||
using ::testing::IsTrue;
|
||||
using ::testing::StartsWith;
|
||||
using ::testing::StrEq;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
} // namespace
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
namespace log_internal {
|
||||
|
||||
class LogEntryTestPeer {
|
||||
public:
|
||||
LogEntryTestPeer(absl::string_view base_filename, int line, bool prefix,
|
||||
absl::LogSeverity severity, absl::string_view timestamp,
|
||||
absl::LogEntry::tid_t tid, PrefixFormat format,
|
||||
absl::string_view text_message)
|
||||
: format_{format}, buf_(15000, '\0') {
|
||||
entry_.base_filename_ = base_filename;
|
||||
entry_.line_ = line;
|
||||
entry_.prefix_ = prefix;
|
||||
entry_.severity_ = severity;
|
||||
std::string time_err;
|
||||
EXPECT_THAT(
|
||||
absl::ParseTime("%Y-%m-%d%ET%H:%M:%E*S", timestamp,
|
||||
absl::LocalTimeZone(), &entry_.timestamp_, &time_err),
|
||||
IsTrue())
|
||||
<< "Failed to parse time " << timestamp << ": " << time_err;
|
||||
entry_.tid_ = tid;
|
||||
std::pair<absl::string_view, std::string> timestamp_bits =
|
||||
absl::StrSplit(timestamp, absl::ByChar('.'));
|
||||
EXPECT_THAT(absl::ParseCivilTime(timestamp_bits.first, &ci_.cs), IsTrue())
|
||||
<< "Failed to parse time " << timestamp_bits.first;
|
||||
timestamp_bits.second.resize(9, '0');
|
||||
int64_t nanos = 0;
|
||||
EXPECT_THAT(absl::SimpleAtoi(timestamp_bits.second, &nanos), IsTrue())
|
||||
<< "Failed to parse time " << timestamp_bits.first;
|
||||
ci_.subsecond = absl::Nanoseconds(nanos);
|
||||
|
||||
absl::Span<char> view = absl::MakeSpan(buf_);
|
||||
view.remove_suffix(2);
|
||||
entry_.prefix_len_ =
|
||||
entry_.prefix_
|
||||
? log_internal::FormatLogPrefix(
|
||||
entry_.log_severity(), entry_.timestamp(), entry_.tid(),
|
||||
entry_.source_basename(), entry_.source_line(), format_, view)
|
||||
: 0;
|
||||
|
||||
EXPECT_THAT(entry_.prefix_len_,
|
||||
Eq(static_cast<size_t>(view.data() - buf_.data())));
|
||||
log_internal::AppendTruncated(text_message, view);
|
||||
view = absl::Span<char>(view.data(), view.size() + 2);
|
||||
view[0] = '\n';
|
||||
view[1] = '\0';
|
||||
view.remove_prefix(2);
|
||||
buf_.resize(static_cast<size_t>(view.data() - buf_.data()));
|
||||
entry_.text_message_with_prefix_and_newline_and_nul_ = absl::MakeSpan(buf_);
|
||||
}
|
||||
LogEntryTestPeer(const LogEntryTestPeer&) = delete;
|
||||
LogEntryTestPeer& operator=(const LogEntryTestPeer&) = delete;
|
||||
|
||||
std::string FormatLogMessage() const {
|
||||
return log_internal::FormatLogMessage(
|
||||
entry_.log_severity(), ci_.cs, ci_.subsecond, entry_.tid(),
|
||||
entry_.source_basename(), entry_.source_line(), format_,
|
||||
entry_.text_message());
|
||||
}
|
||||
std::string FormatPrefixIntoSizedBuffer(size_t sz) {
|
||||
std::string str(sz, '\0');
|
||||
absl::Span<char> buf(&str[0], str.size());
|
||||
const size_t prefix_size = log_internal::FormatLogPrefix(
|
||||
entry_.log_severity(), entry_.timestamp(), entry_.tid(),
|
||||
entry_.source_basename(), entry_.source_line(), format_, buf);
|
||||
EXPECT_THAT(prefix_size, Eq(static_cast<size_t>(buf.data() - str.data())));
|
||||
str.resize(prefix_size);
|
||||
return str;
|
||||
}
|
||||
const absl::LogEntry& entry() const { return entry_; }
|
||||
|
||||
private:
|
||||
absl::LogEntry entry_;
|
||||
PrefixFormat format_;
|
||||
absl::TimeZone::CivilInfo ci_;
|
||||
std::vector<char> buf_;
|
||||
};
|
||||
|
||||
} // namespace log_internal
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
namespace {
|
||||
constexpr bool kUsePrefix = true, kNoPrefix = false;
|
||||
|
||||
TEST(LogEntryTest, Baseline) {
|
||||
LogEntryTestPeer entry("foo.cc", 1234, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.6789", 451,
|
||||
absl::log_internal::PrefixFormat::kNotRaw,
|
||||
"hello world");
|
||||
EXPECT_THAT(entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world"));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] "));
|
||||
for (size_t sz = strlen("I0102 03:04:05.678900 451 foo.cc:1234] ") + 20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:1234] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678900 451 foo.cc:1234] hello world\n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world"));
|
||||
EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
|
||||
}
|
||||
|
||||
TEST(LogEntryTest, NoPrefix) {
|
||||
LogEntryTestPeer entry("foo.cc", 1234, kNoPrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.6789", 451,
|
||||
absl::log_internal::PrefixFormat::kNotRaw,
|
||||
"hello world");
|
||||
EXPECT_THAT(entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] hello world"));
|
||||
// These methods are not responsible for honoring `prefix()`.
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] "));
|
||||
for (size_t sz = strlen("I0102 03:04:05.678900 451 foo.cc:1234] ") + 20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:1234] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("hello world\n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("hello world\n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix(), Eq("hello world"));
|
||||
EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
|
||||
}
|
||||
|
||||
TEST(LogEntryTest, EmptyFields) {
|
||||
LogEntryTestPeer entry("", 0, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05", 0,
|
||||
absl::log_internal::PrefixFormat::kNotRaw, "");
|
||||
const std::string format_message = entry.FormatLogMessage();
|
||||
EXPECT_THAT(format_message, Eq("I0102 03:04:05.000000 0 :0] "));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000), Eq(format_message));
|
||||
for (size_t sz = format_message.size() + 20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT(format_message,
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.000000 0 :0] \n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.000000 0 :0] \n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.000000 0 :0] "));
|
||||
EXPECT_THAT(entry.entry().text_message(), Eq(""));
|
||||
}
|
||||
|
||||
TEST(LogEntryTest, NegativeFields) {
|
||||
// When Abseil's minimum C++ version is C++17, this conditional can be
|
||||
// converted to a constexpr if and the static_cast below removed.
|
||||
if (std::is_signed<absl::LogEntry::tid_t>::value) {
|
||||
LogEntryTestPeer entry(
|
||||
"foo.cc", -1234, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.6789", static_cast<absl::LogEntry::tid_t>(-451),
|
||||
absl::log_internal::PrefixFormat::kNotRaw, "hello world");
|
||||
EXPECT_THAT(entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world"));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] "));
|
||||
for (size_t sz =
|
||||
strlen("I0102 03:04:05.678900 -451 foo.cc:-1234] ") + 20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT("I0102 03:04:05.678900 -451 foo.cc:-1234] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world\n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678900 -451 foo.cc:-1234] hello world"));
|
||||
EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
|
||||
} else {
|
||||
LogEntryTestPeer entry("foo.cc", -1234, kUsePrefix,
|
||||
absl::LogSeverity::kInfo, "2020-01-02T03:04:05.6789",
|
||||
451, absl::log_internal::PrefixFormat::kNotRaw,
|
||||
"hello world");
|
||||
EXPECT_THAT(entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world"));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:-1234] "));
|
||||
for (size_t sz =
|
||||
strlen("I0102 03:04:05.678900 451 foo.cc:-1234] ") + 20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:-1234] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world\n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:-1234] hello world"));
|
||||
EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LogEntryTest, LongFields) {
|
||||
LogEntryTestPeer entry(
|
||||
"I am the very model of a modern Major-General / "
|
||||
"I've information vegetable, animal, and mineral.",
|
||||
2147483647, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.678967896789", 2147483647,
|
||||
absl::log_internal::PrefixFormat::kNotRaw,
|
||||
"I know the kings of England, and I quote the fights historical / "
|
||||
"From Marathon to Waterloo, in order categorical.");
|
||||
EXPECT_THAT(entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical."));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] "));
|
||||
for (size_t sz =
|
||||
strlen("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] ") +
|
||||
20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT(
|
||||
"I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical.\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical.\n"));
|
||||
EXPECT_THAT(entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical."));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message(),
|
||||
Eq("I know the kings of England, and I quote the fights historical / "
|
||||
"From Marathon to Waterloo, in order categorical."));
|
||||
}
|
||||
|
||||
TEST(LogEntryTest, LongNegativeFields) {
|
||||
// When Abseil's minimum C++ version is C++17, this conditional can be
|
||||
// converted to a constexpr if and the static_cast below removed.
|
||||
if (std::is_signed<absl::LogEntry::tid_t>::value) {
|
||||
LogEntryTestPeer entry(
|
||||
"I am the very model of a modern Major-General / "
|
||||
"I've information vegetable, animal, and mineral.",
|
||||
-2147483647, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.678967896789",
|
||||
static_cast<absl::LogEntry::tid_t>(-2147483647),
|
||||
absl::log_internal::PrefixFormat::kNotRaw,
|
||||
"I know the kings of England, and I quote the fights historical / "
|
||||
"From Marathon to Waterloo, in order categorical.");
|
||||
EXPECT_THAT(
|
||||
entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical."));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] "));
|
||||
for (size_t sz =
|
||||
strlen(
|
||||
"I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] ") +
|
||||
20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT(
|
||||
"I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical.\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical.\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678967 -2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical."));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message(),
|
||||
Eq("I know the kings of England, and I quote the fights historical / "
|
||||
"From Marathon to Waterloo, in order categorical."));
|
||||
} else {
|
||||
LogEntryTestPeer entry(
|
||||
"I am the very model of a modern Major-General / "
|
||||
"I've information vegetable, animal, and mineral.",
|
||||
-2147483647, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.678967896789", 2147483647,
|
||||
absl::log_internal::PrefixFormat::kNotRaw,
|
||||
"I know the kings of England, and I quote the fights historical / "
|
||||
"From Marathon to Waterloo, in order categorical.");
|
||||
EXPECT_THAT(
|
||||
entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical."));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] "));
|
||||
for (size_t sz =
|
||||
strlen(
|
||||
"I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] ") +
|
||||
20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT(
|
||||
"I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical.\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical.\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678967 2147483647 I am the very model of a "
|
||||
"modern Major-General / I've information vegetable, animal, "
|
||||
"and mineral.:-2147483647] I know the kings of England, and I "
|
||||
"quote the fights historical / From Marathon to Waterloo, in "
|
||||
"order categorical."));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message(),
|
||||
Eq("I know the kings of England, and I quote the fights historical / "
|
||||
"From Marathon to Waterloo, in order categorical."));
|
||||
}
|
||||
}
|
||||
|
||||
TEST(LogEntryTest, Raw) {
|
||||
LogEntryTestPeer entry("foo.cc", 1234, kUsePrefix, absl::LogSeverity::kInfo,
|
||||
"2020-01-02T03:04:05.6789", 451,
|
||||
absl::log_internal::PrefixFormat::kRaw, "hello world");
|
||||
EXPECT_THAT(
|
||||
entry.FormatLogMessage(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world"));
|
||||
EXPECT_THAT(entry.FormatPrefixIntoSizedBuffer(1000),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: "));
|
||||
for (size_t sz =
|
||||
strlen("I0102 03:04:05.678900 451 foo.cc:1234] RAW: ") + 20;
|
||||
sz != std::numeric_limits<size_t>::max(); sz--)
|
||||
EXPECT_THAT("I0102 03:04:05.678900 451 foo.cc:1234] RAW: ",
|
||||
StartsWith(entry.FormatPrefixIntoSizedBuffer(sz)));
|
||||
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix_and_newline_c_str(),
|
||||
StrEq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world\n"));
|
||||
EXPECT_THAT(
|
||||
entry.entry().text_message_with_prefix(),
|
||||
Eq("I0102 03:04:05.678900 451 foo.cc:1234] RAW: hello world"));
|
||||
EXPECT_THAT(entry.entry().text_message(), Eq("hello world"));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
1855
TMessagesProj/jni/voip/webrtc/absl/log/log_format_test.cc
Normal file
1855
TMessagesProj/jni/voip/webrtc/absl/log/log_format_test.cc
Normal file
File diff suppressed because it is too large
Load diff
187
TMessagesProj/jni/voip/webrtc/absl/log/log_macro_hygiene_test.cc
Normal file
187
TMessagesProj/jni/voip/webrtc/absl/log/log_macro_hygiene_test.cc
Normal file
|
|
@ -0,0 +1,187 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
|
||||
namespace {
|
||||
using ::testing::_;
|
||||
using ::testing::Eq;
|
||||
|
||||
namespace not_absl {
|
||||
|
||||
class Dummy {
|
||||
public:
|
||||
Dummy() {}
|
||||
|
||||
private:
|
||||
Dummy(const Dummy&) = delete;
|
||||
Dummy& operator=(const Dummy&) = delete;
|
||||
};
|
||||
|
||||
// This line tests that local definitions of INFO, WARNING, ERROR, and
|
||||
// etc don't shadow the global ones used by the logging macros. If
|
||||
// they do, the LOG() calls in the tests won't compile, catching the
|
||||
// bug.
|
||||
const Dummy INFO, WARNING, ERROR, FATAL, NUM_SEVERITIES;
|
||||
|
||||
// These makes sure that the uses of same-named types in the
|
||||
// implementation of the logging macros are fully qualified.
|
||||
class string {};
|
||||
class vector {};
|
||||
class LogMessage {};
|
||||
class LogMessageFatal {};
|
||||
class LogMessageQuietlyFatal {};
|
||||
class LogMessageVoidify {};
|
||||
class LogSink {};
|
||||
class NullStream {};
|
||||
class NullStreamFatal {};
|
||||
|
||||
} // namespace not_absl
|
||||
|
||||
using namespace not_absl; // NOLINT
|
||||
|
||||
// Tests for LOG(LEVEL(()).
|
||||
|
||||
TEST(LogHygieneTest, WorksForQualifiedSeverity) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
::testing::InSequence seq;
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "To INFO"));
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "To WARNING"));
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "To ERROR"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
// Note that LOG(LEVEL()) expects the severity as a run-time
|
||||
// expression (as opposed to a compile-time constant). Hence we
|
||||
// test that :: is allowed before INFO, etc.
|
||||
LOG(LEVEL(absl::LogSeverity::kInfo)) << "To INFO";
|
||||
LOG(LEVEL(absl::LogSeverity::kWarning)) << "To WARNING";
|
||||
LOG(LEVEL(absl::LogSeverity::kError)) << "To ERROR";
|
||||
}
|
||||
|
||||
TEST(LogHygieneTest, WorksWithAlternativeINFOSymbol) {
|
||||
const double INFO ABSL_ATTRIBUTE_UNUSED = 7.77;
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO) << "Hello world";
|
||||
}
|
||||
|
||||
TEST(LogHygieneTest, WorksWithAlternativeWARNINGSymbol) {
|
||||
const double WARNING ABSL_ATTRIBUTE_UNUSED = 7.77;
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "Hello world"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(WARNING) << "Hello world";
|
||||
}
|
||||
|
||||
TEST(LogHygieneTest, WorksWithAlternativeERRORSymbol) {
|
||||
const double ERROR ABSL_ATTRIBUTE_UNUSED = 7.77;
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(ERROR) << "Hello world";
|
||||
}
|
||||
|
||||
TEST(LogHygieneTest, WorksWithAlternativeLEVELSymbol) {
|
||||
const double LEVEL ABSL_ATTRIBUTE_UNUSED = 7.77;
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kError, _, "Hello world"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(LEVEL(absl::LogSeverity::kError)) << "Hello world";
|
||||
}
|
||||
|
||||
#define INFO Bogus
|
||||
#ifdef NDEBUG
|
||||
constexpr bool IsOptimized = false;
|
||||
#else
|
||||
constexpr bool IsOptimized = true;
|
||||
#endif
|
||||
|
||||
TEST(LogHygieneTest, WorksWithINFODefined) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"))
|
||||
.Times(2 + (IsOptimized ? 2 : 0));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO) << "Hello world";
|
||||
LOG_IF(INFO, true) << "Hello world";
|
||||
|
||||
DLOG(INFO) << "Hello world";
|
||||
DLOG_IF(INFO, true) << "Hello world";
|
||||
}
|
||||
|
||||
#undef INFO
|
||||
|
||||
#define _INFO Bogus
|
||||
TEST(LogHygieneTest, WorksWithUnderscoreINFODefined) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "Hello world"))
|
||||
.Times(2 + (IsOptimized ? 2 : 0));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO) << "Hello world";
|
||||
LOG_IF(INFO, true) << "Hello world";
|
||||
|
||||
DLOG(INFO) << "Hello world";
|
||||
DLOG_IF(INFO, true) << "Hello world";
|
||||
}
|
||||
#undef _INFO
|
||||
|
||||
TEST(LogHygieneTest, ExpressionEvaluationInLEVELSeverity) {
|
||||
auto i = static_cast<int>(absl::LogSeverity::kInfo);
|
||||
LOG(LEVEL(++i)) << "hello world"; // NOLINT
|
||||
EXPECT_THAT(i, Eq(static_cast<int>(absl::LogSeverity::kInfo) + 1));
|
||||
}
|
||||
|
||||
TEST(LogHygieneTest, ExpressionEvaluationInStreamedMessage) {
|
||||
int i = 0;
|
||||
LOG(INFO) << ++i;
|
||||
EXPECT_THAT(i, 1);
|
||||
LOG_IF(INFO, false) << ++i;
|
||||
EXPECT_THAT(i, 1);
|
||||
}
|
||||
|
||||
// Tests that macros are usable in unbraced switch statements.
|
||||
// -----------------------------------------------------------
|
||||
|
||||
class UnbracedSwitchCompileTest {
|
||||
static void Log() {
|
||||
switch (0) {
|
||||
case 0:
|
||||
LOG(INFO);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include <errno.h>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/log/internal/test_actions.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/time/time.h"
|
||||
|
||||
namespace {
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
using ::absl::log_internal::DeathTestExpectedLogging;
|
||||
using ::absl::log_internal::DeathTestUnexpectedLogging;
|
||||
using ::absl::log_internal::DeathTestValidateExpectations;
|
||||
using ::absl::log_internal::DiedOfQFatal;
|
||||
#endif
|
||||
using ::absl::log_internal::LogSeverity;
|
||||
using ::absl::log_internal::Prefix;
|
||||
using ::absl::log_internal::SourceBasename;
|
||||
using ::absl::log_internal::SourceFilename;
|
||||
using ::absl::log_internal::SourceLine;
|
||||
using ::absl::log_internal::Stacktrace;
|
||||
using ::absl::log_internal::TextMessage;
|
||||
using ::absl::log_internal::TextMessageWithPrefix;
|
||||
using ::absl::log_internal::TextMessageWithPrefixAndNewline;
|
||||
using ::absl::log_internal::TextPrefix;
|
||||
using ::absl::log_internal::ThreadID;
|
||||
using ::absl::log_internal::Timestamp;
|
||||
using ::absl::log_internal::Verbosity;
|
||||
|
||||
using ::testing::AllOf;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::AnyOf;
|
||||
using ::testing::Eq;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsFalse;
|
||||
using ::testing::Truly;
|
||||
|
||||
TEST(TailCallsModifiesTest, AtLocationFileLine) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
// The metadata should change:
|
||||
SourceFilename(Eq("/my/very/very/very_long_source_file.cc")),
|
||||
SourceBasename(Eq("very_long_source_file.cc")), SourceLine(Eq(777)),
|
||||
// The logged line should change too, even though the prefix must
|
||||
// grow to fit the new metadata.
|
||||
TextMessageWithPrefix(Truly([](absl::string_view msg) {
|
||||
return absl::EndsWith(msg,
|
||||
" very_long_source_file.cc:777] hello world");
|
||||
})))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).AtLocation("/my/very/very/very_long_source_file.cc", 777)
|
||||
<< "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, NoPrefix) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()),
|
||||
TextMessageWithPrefix(Eq("hello world")))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).NoPrefix() << "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, NoPrefixNoMessageNoShirtNoShoesNoService) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink,
|
||||
Send(AllOf(Prefix(IsFalse()), TextPrefix(IsEmpty()),
|
||||
TextMessageWithPrefix(IsEmpty()),
|
||||
TextMessageWithPrefixAndNewline(Eq("\n")))));
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).NoPrefix();
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, WithVerbosity) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(Verbosity(Eq(2))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).WithVerbosity(2) << "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, WithVerbosityNoVerbosity) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink,
|
||||
Send(Verbosity(Eq(absl::LogEntry::kNoVerbosityLevel))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).WithVerbosity(2).WithVerbosity(absl::LogEntry::kNoVerbosityLevel)
|
||||
<< "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, WithTimestamp) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(Timestamp(Eq(absl::UnixEpoch()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).WithTimestamp(absl::UnixEpoch()) << "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, WithThreadID) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink,
|
||||
Send(AllOf(ThreadID(Eq(absl::LogEntry::tid_t{1234})))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).WithThreadID(1234) << "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, WithMetadataFrom) {
|
||||
class ForwardingLogSink : public absl::LogSink {
|
||||
public:
|
||||
void Send(const absl::LogEntry &entry) override {
|
||||
LOG(LEVEL(entry.log_severity())).WithMetadataFrom(entry)
|
||||
<< "forwarded: " << entry.text_message();
|
||||
}
|
||||
} forwarding_sink;
|
||||
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq("fake/file")), SourceBasename(Eq("file")),
|
||||
SourceLine(Eq(123)), Prefix(IsFalse()),
|
||||
LogSeverity(Eq(absl::LogSeverity::kWarning)),
|
||||
Timestamp(Eq(absl::UnixEpoch())),
|
||||
ThreadID(Eq(absl::LogEntry::tid_t{456})),
|
||||
TextMessage(Eq("forwarded: hello world")), Verbosity(Eq(7)),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("fake/file"), Eq(123), Eq(absl::UnixEpoch()),
|
||||
Eq(logging::proto::WARNING), Eq(456),
|
||||
ElementsAre(ValueWithLiteral(Eq("forwarded: ")),
|
||||
ValueWithStr(Eq("hello world"))))))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(WARNING)
|
||||
.AtLocation("fake/file", 123)
|
||||
.NoPrefix()
|
||||
.WithTimestamp(absl::UnixEpoch())
|
||||
.WithThreadID(456)
|
||||
.WithVerbosity(7)
|
||||
.ToSinkOnly(&forwarding_sink)
|
||||
<< "hello world";
|
||||
}
|
||||
|
||||
TEST(TailCallsModifiesTest, WithPerror) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
TextMessage(AnyOf(Eq("hello world: Bad file number [9]"),
|
||||
Eq("hello world: Bad file descriptor [9]"),
|
||||
Eq("hello world: Bad file descriptor [8]"))),
|
||||
ENCODED_MESSAGE(HasValues(ElementsAre(
|
||||
ValueWithLiteral(Eq("hello world")), ValueWithLiteral(Eq(": ")),
|
||||
AnyOf(ValueWithStr(Eq("Bad file number")),
|
||||
ValueWithStr(Eq("Bad file descriptor"))),
|
||||
ValueWithLiteral(Eq(" [")),
|
||||
AnyOf(ValueWithStr(Eq("8")), ValueWithStr(Eq("9"))),
|
||||
ValueWithLiteral(Eq("]"))))))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
errno = EBADF;
|
||||
LOG(INFO).WithPerror() << "hello world";
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(ModifierMethodDeathTest, ToSinkOnlyQFatal) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink(
|
||||
absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
auto do_log = [&test_sink] {
|
||||
LOG(QFATAL).ToSinkOnly(&test_sink.UseAsLocalSink()) << "hello world";
|
||||
};
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("hello world")),
|
||||
Stacktrace(IsEmpty()))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
do_log();
|
||||
},
|
||||
DiedOfQFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
} // namespace
|
||||
23
TMessagesProj/jni/voip/webrtc/absl/log/log_sink.cc
Normal file
23
TMessagesProj/jni/voip/webrtc/absl/log/log_sink.cc
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
// Copyright 2022 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/log_sink.h"
|
||||
|
||||
#include "absl/base/config.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
void LogSink::KeyFunction() const {}
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
71
TMessagesProj/jni/voip/webrtc/absl/log/log_sink.h
Normal file
71
TMessagesProj/jni/voip/webrtc/absl/log/log_sink.h
Normal file
|
|
@ -0,0 +1,71 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/log_sink.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares the interface class `absl::LogSink`.
|
||||
|
||||
#ifndef ABSL_LOG_LOG_SINK_H_
|
||||
#define ABSL_LOG_LOG_SINK_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// absl::LogSink
|
||||
//
|
||||
// `absl::LogSink` is an interface which can be extended to intercept and
|
||||
// process particular messages (with `LOG.ToSinkOnly()` or
|
||||
// `LOG.ToSinkAlso()`) or all messages (if registered with
|
||||
// `absl::AddLogSink`). Implementations must not take any locks that might be
|
||||
// held by the `LOG` caller.
|
||||
class LogSink {
|
||||
public:
|
||||
virtual ~LogSink() = default;
|
||||
|
||||
// LogSink::Send()
|
||||
//
|
||||
// `Send` is called synchronously during the log statement. `Send` must be
|
||||
// thread-safe.
|
||||
//
|
||||
// It is safe to use `LOG` within an implementation of `Send`. `ToSinkOnly`
|
||||
// and `ToSinkAlso` are safe in general but can be used to create an infinite
|
||||
// loop if you try.
|
||||
virtual void Send(const absl::LogEntry& entry) = 0;
|
||||
|
||||
// LogSink::Flush()
|
||||
//
|
||||
// Sinks that buffer messages should override this method to flush the buffer
|
||||
// and return. `Flush` must be thread-safe.
|
||||
virtual void Flush() {}
|
||||
|
||||
protected:
|
||||
LogSink() = default;
|
||||
// Implementations may be copyable and/or movable.
|
||||
LogSink(const LogSink&) = default;
|
||||
LogSink& operator=(const LogSink&) = default;
|
||||
|
||||
private:
|
||||
// https://lld.llvm.org/missingkeyfunction.html#missing-key-function
|
||||
virtual void KeyFunction() const final; // NOLINT(readability/inheritance)
|
||||
};
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_LOG_SINK_H_
|
||||
64
TMessagesProj/jni/voip/webrtc/absl/log/log_sink_registry.h
Normal file
64
TMessagesProj/jni/voip/webrtc/absl/log/log_sink_registry.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/log_sink_registry.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares APIs to operate on global set of registered log sinks.
|
||||
|
||||
#ifndef ABSL_LOG_LOG_SINK_REGISTRY_H_
|
||||
#define ABSL_LOG_LOG_SINK_REGISTRY_H_
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/nullability.h"
|
||||
#include "absl/log/internal/log_sink_set.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// AddLogSink(), RemoveLogSink()
|
||||
//
|
||||
// Adds or removes a `absl::LogSink` as a consumer of logging data.
|
||||
//
|
||||
// These functions are thread-safe.
|
||||
//
|
||||
// It is an error to attempt to add a sink that's already registered or to
|
||||
// attempt to remove one that isn't.
|
||||
//
|
||||
// To avoid unbounded recursion, dispatch to registered `absl::LogSink`s is
|
||||
// disabled per-thread while running the `Send()` method of registered
|
||||
// `absl::LogSink`s. Affected messages are dispatched to a special internal
|
||||
// sink instead which writes them to `stderr`.
|
||||
//
|
||||
// Do not call these inside `absl::LogSink::Send`.
|
||||
inline void AddLogSink(absl::Nonnull<absl::LogSink*> sink) {
|
||||
log_internal::AddLogSink(sink);
|
||||
}
|
||||
inline void RemoveLogSink(absl::Nonnull<absl::LogSink*> sink) {
|
||||
log_internal::RemoveLogSink(sink);
|
||||
}
|
||||
|
||||
// FlushLogSinks()
|
||||
//
|
||||
// Calls `absl::LogSink::Flush` on all registered sinks.
|
||||
//
|
||||
// Do not call this inside `absl::LogSink::Send`.
|
||||
inline void FlushLogSinks() { log_internal::FlushLogSinks(); }
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_LOG_SINK_REGISTRY_H_
|
||||
418
TMessagesProj/jni/voip/webrtc/absl/log/log_sink_test.cc
Normal file
418
TMessagesProj/jni/voip/webrtc/absl/log/log_sink_test.cc
Normal file
|
|
@ -0,0 +1,418 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/log_sink.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/log/internal/test_actions.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/log_sink_registry.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::absl::log_internal::DeathTestExpectedLogging;
|
||||
using ::absl::log_internal::DeathTestUnexpectedLogging;
|
||||
using ::absl::log_internal::DeathTestValidateExpectations;
|
||||
using ::absl::log_internal::DiedOfFatal;
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::InSequence;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
// Tests for global log sink registration.
|
||||
// ---------------------------------------
|
||||
|
||||
TEST(LogSinkRegistryTest, AddLogSink) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world")).Times(0);
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, __FILE__, "Test : 42"));
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(absl::LogSeverity::kWarning, __FILE__, "Danger ahead"));
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(absl::LogSeverity::kError, __FILE__, "This is an error"));
|
||||
|
||||
LOG(INFO) << "hello world";
|
||||
test_sink.StartCapturingLogs();
|
||||
|
||||
LOG(INFO) << "Test : " << 42;
|
||||
LOG(WARNING) << "Danger" << ' ' << "ahead";
|
||||
LOG(ERROR) << "This is an error";
|
||||
|
||||
test_sink.StopCapturingLogs();
|
||||
LOG(INFO) << "Goodby world";
|
||||
}
|
||||
|
||||
TEST(LogSinkRegistryTest, MultipleLogSinks) {
|
||||
absl::ScopedMockLog test_sink1(absl::MockLogDefault::kDisallowUnexpected);
|
||||
absl::ScopedMockLog test_sink2(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
::testing::InSequence seq;
|
||||
EXPECT_CALL(test_sink1, Log(absl::LogSeverity::kInfo, _, "First")).Times(1);
|
||||
EXPECT_CALL(test_sink2, Log(absl::LogSeverity::kInfo, _, "First")).Times(0);
|
||||
|
||||
EXPECT_CALL(test_sink1, Log(absl::LogSeverity::kInfo, _, "Second")).Times(1);
|
||||
EXPECT_CALL(test_sink2, Log(absl::LogSeverity::kInfo, _, "Second")).Times(1);
|
||||
|
||||
EXPECT_CALL(test_sink1, Log(absl::LogSeverity::kInfo, _, "Third")).Times(0);
|
||||
EXPECT_CALL(test_sink2, Log(absl::LogSeverity::kInfo, _, "Third")).Times(1);
|
||||
|
||||
LOG(INFO) << "Before first";
|
||||
|
||||
test_sink1.StartCapturingLogs();
|
||||
LOG(INFO) << "First";
|
||||
|
||||
test_sink2.StartCapturingLogs();
|
||||
LOG(INFO) << "Second";
|
||||
|
||||
test_sink1.StopCapturingLogs();
|
||||
LOG(INFO) << "Third";
|
||||
|
||||
test_sink2.StopCapturingLogs();
|
||||
LOG(INFO) << "Fourth";
|
||||
}
|
||||
|
||||
TEST(LogSinkRegistrationDeathTest, DuplicateSinkRegistration) {
|
||||
ASSERT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::ScopedMockLog sink;
|
||||
sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&sink.UseAsLocalSink());
|
||||
},
|
||||
HasSubstr("Duplicate log sinks"));
|
||||
}
|
||||
|
||||
TEST(LogSinkRegistrationDeathTest, MismatchSinkRemoval) {
|
||||
ASSERT_DEATH_IF_SUPPORTED(
|
||||
{
|
||||
absl::ScopedMockLog sink;
|
||||
absl::RemoveLogSink(&sink.UseAsLocalSink());
|
||||
},
|
||||
HasSubstr("Mismatched log sink"));
|
||||
}
|
||||
|
||||
// Tests for log sink semantic.
|
||||
// ---------------------------------------
|
||||
|
||||
TEST(LogSinkTest, FlushSinks) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Flush()).Times(2);
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
|
||||
absl::FlushLogSinks();
|
||||
absl::FlushLogSinks();
|
||||
}
|
||||
|
||||
TEST(LogSinkDeathTest, DeathInSend) {
|
||||
class FatalSendSink : public absl::LogSink {
|
||||
public:
|
||||
void Send(const absl::LogEntry&) override { LOG(FATAL) << "goodbye world"; }
|
||||
};
|
||||
|
||||
FatalSendSink sink;
|
||||
EXPECT_EXIT({ LOG(INFO).ToSinkAlso(&sink) << "hello world"; }, DiedOfFatal,
|
||||
_);
|
||||
}
|
||||
|
||||
// Tests for explicit log sink redirection.
|
||||
// ---------------------------------------
|
||||
|
||||
TEST(LogSinkTest, ToSinkAlso) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
absl::ScopedMockLog another_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"));
|
||||
EXPECT_CALL(another_sink, Log(_, _, "hello world"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).ToSinkAlso(&another_sink.UseAsLocalSink()) << "hello world";
|
||||
}
|
||||
|
||||
TEST(LogSinkTest, ToSinkOnly) {
|
||||
absl::ScopedMockLog another_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
EXPECT_CALL(another_sink, Log(_, _, "hello world"));
|
||||
LOG(INFO).ToSinkOnly(&another_sink.UseAsLocalSink()) << "hello world";
|
||||
}
|
||||
|
||||
TEST(LogSinkTest, ToManySinks) {
|
||||
absl::ScopedMockLog sink1(absl::MockLogDefault::kDisallowUnexpected);
|
||||
absl::ScopedMockLog sink2(absl::MockLogDefault::kDisallowUnexpected);
|
||||
absl::ScopedMockLog sink3(absl::MockLogDefault::kDisallowUnexpected);
|
||||
absl::ScopedMockLog sink4(absl::MockLogDefault::kDisallowUnexpected);
|
||||
absl::ScopedMockLog sink5(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(sink3, Log(_, _, "hello world"));
|
||||
EXPECT_CALL(sink4, Log(_, _, "hello world"));
|
||||
EXPECT_CALL(sink5, Log(_, _, "hello world"));
|
||||
|
||||
LOG(INFO)
|
||||
.ToSinkAlso(&sink1.UseAsLocalSink())
|
||||
.ToSinkAlso(&sink2.UseAsLocalSink())
|
||||
.ToSinkOnly(&sink3.UseAsLocalSink())
|
||||
.ToSinkAlso(&sink4.UseAsLocalSink())
|
||||
.ToSinkAlso(&sink5.UseAsLocalSink())
|
||||
<< "hello world";
|
||||
}
|
||||
|
||||
class ReentrancyTest : public ::testing::Test {
|
||||
protected:
|
||||
ReentrancyTest() = default;
|
||||
enum class LogMode : int { kNormal, kToSinkAlso, kToSinkOnly };
|
||||
|
||||
class ReentrantSendLogSink : public absl::LogSink {
|
||||
public:
|
||||
explicit ReentrantSendLogSink(absl::LogSeverity severity,
|
||||
absl::LogSink* sink, LogMode mode)
|
||||
: severity_(severity), sink_(sink), mode_(mode) {}
|
||||
explicit ReentrantSendLogSink(absl::LogSeverity severity)
|
||||
: ReentrantSendLogSink(severity, nullptr, LogMode::kNormal) {}
|
||||
|
||||
void Send(const absl::LogEntry&) override {
|
||||
switch (mode_) {
|
||||
case LogMode::kNormal:
|
||||
LOG(LEVEL(severity_)) << "The log is coming from *inside the sink*.";
|
||||
break;
|
||||
case LogMode::kToSinkAlso:
|
||||
LOG(LEVEL(severity_)).ToSinkAlso(sink_)
|
||||
<< "The log is coming from *inside the sink*.";
|
||||
break;
|
||||
case LogMode::kToSinkOnly:
|
||||
LOG(LEVEL(severity_)).ToSinkOnly(sink_)
|
||||
<< "The log is coming from *inside the sink*.";
|
||||
break;
|
||||
default:
|
||||
LOG(FATAL) << "Invalid mode " << static_cast<int>(mode_);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
absl::LogSeverity severity_;
|
||||
absl::LogSink* sink_;
|
||||
LogMode mode_;
|
||||
};
|
||||
|
||||
static absl::string_view LogAndReturn(absl::LogSeverity severity,
|
||||
absl::string_view to_log,
|
||||
absl::string_view to_return) {
|
||||
LOG(LEVEL(severity)) << to_log;
|
||||
return to_return;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(ReentrancyTest, LogFunctionThatLogs) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
InSequence seq;
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "hello"));
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "world"));
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kWarning, _, "danger"));
|
||||
EXPECT_CALL(test_sink, Log(absl::LogSeverity::kInfo, _, "here"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO) << LogAndReturn(absl::LogSeverity::kInfo, "hello", "world");
|
||||
LOG(INFO) << LogAndReturn(absl::LogSeverity::kWarning, "danger", "here");
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyTest, RegisteredLogSinkThatLogsInSend) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
ReentrantSendLogSink renentrant_sink(absl::LogSeverity::kInfo);
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&renentrant_sink);
|
||||
LOG(INFO) << "hello world";
|
||||
absl::RemoveLogSink(&renentrant_sink);
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyTest, AlsoLogSinkThatLogsInSend) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kInfo);
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"));
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).ToSinkAlso(&reentrant_sink) << "hello world";
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyTest, RegisteredAlsoLogSinkThatLogsInSend) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kInfo);
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"));
|
||||
// We only call into the test_log sink once with this message, since the
|
||||
// second time log statement is run we are in "ThreadIsLogging" mode and all
|
||||
// the log statements are redirected into stderr.
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&reentrant_sink);
|
||||
LOG(INFO).ToSinkAlso(&reentrant_sink) << "hello world";
|
||||
absl::RemoveLogSink(&reentrant_sink);
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyTest, OnlyLogSinkThatLogsInSend) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kInfo);
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).ToSinkOnly(&reentrant_sink) << "hello world";
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyTest, RegisteredOnlyLogSinkThatLogsInSend) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kInfo);
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&reentrant_sink);
|
||||
LOG(INFO).ToSinkOnly(&reentrant_sink) << "hello world";
|
||||
absl::RemoveLogSink(&reentrant_sink);
|
||||
}
|
||||
|
||||
using ReentrancyDeathTest = ReentrancyTest;
|
||||
|
||||
TEST_F(ReentrancyDeathTest, LogFunctionThatLogsFatal) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello"))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO) << LogAndReturn(absl::LogSeverity::kFatal, "hello", "world");
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyDeathTest, RegisteredLogSinkThatLogsFatalInSend) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kFatal);
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&reentrant_sink);
|
||||
LOG(INFO) << "hello world";
|
||||
// No need to call RemoveLogSink - process is dead at this point.
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyDeathTest, AlsoLogSinkThatLogsFatalInSend) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kFatal);
|
||||
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).ToSinkAlso(&reentrant_sink) << "hello world";
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyDeathTest, RegisteredAlsoLogSinkThatLogsFatalInSend) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kFatal);
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
EXPECT_CALL(test_sink, Log(_, _, "hello world"))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&reentrant_sink);
|
||||
LOG(INFO).ToSinkAlso(&reentrant_sink) << "hello world";
|
||||
// No need to call RemoveLogSink - process is dead at this point.
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyDeathTest, OnlyLogSinkThatLogsFatalInSend) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kFatal);
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
LOG(INFO).ToSinkOnly(&reentrant_sink) << "hello world";
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
TEST_F(ReentrancyDeathTest, RegisteredOnlyLogSinkThatLogsFatalInSend) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
ReentrantSendLogSink reentrant_sink(absl::LogSeverity::kFatal);
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
EXPECT_CALL(test_sink,
|
||||
Log(_, _, "The log is coming from *inside the sink*."))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::AddLogSink(&reentrant_sink);
|
||||
LOG(INFO).ToSinkOnly(&reentrant_sink) << "hello world";
|
||||
// No need to call RemoveLogSink - process is dead at this point.
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
|
||||
} // namespace
|
||||
181
TMessagesProj/jni/voip/webrtc/absl/log/log_streamer.h
Normal file
181
TMessagesProj/jni/voip/webrtc/absl/log/log_streamer.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/log_streamer.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares the class `LogStreamer` and convenience functions to
|
||||
// construct LogStreamer objects with different associated log severity levels.
|
||||
|
||||
#ifndef ABSL_LOG_LOG_STREAMER_H_
|
||||
#define ABSL_LOG_LOG_STREAMER_H_
|
||||
|
||||
#include <ios>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/absl_log.h"
|
||||
#include "absl/strings/internal/ostringstream.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/types/optional.h"
|
||||
#include "absl/utility/utility.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// LogStreamer
|
||||
//
|
||||
// Although you can stream into `LOG(INFO)`, you can't pass it into a function
|
||||
// that takes a `std::ostream` parameter. `LogStreamer::stream()` provides a
|
||||
// `std::ostream` that buffers everything that's streamed in. The buffer's
|
||||
// contents are logged as if by `LOG` when the `LogStreamer` is destroyed.
|
||||
// If nothing is streamed in, an empty message is logged. If the specified
|
||||
// severity is `absl::LogSeverity::kFatal`, the program will be terminated when
|
||||
// the `LogStreamer` is destroyed regardless of whether any data were streamed
|
||||
// in.
|
||||
//
|
||||
// Factory functions corresponding to the `absl::LogSeverity` enumerators
|
||||
// are provided for convenience; if the desired severity is variable, invoke the
|
||||
// constructor directly.
|
||||
//
|
||||
// LogStreamer is movable, but not copyable.
|
||||
//
|
||||
// Examples:
|
||||
//
|
||||
// ShaveYakAndWriteToStream(
|
||||
// yak, absl::LogInfoStreamer(__FILE__, __LINE__).stream());
|
||||
//
|
||||
// {
|
||||
// // This logs a single line containing data streamed by all three function
|
||||
// // calls.
|
||||
// absl::LogStreamer streamer(absl::LogSeverity::kInfo, __FILE__, __LINE__);
|
||||
// ShaveYakAndWriteToStream(yak1, streamer.stream());
|
||||
// streamer.stream() << " ";
|
||||
// ShaveYakAndWriteToStream(yak2, streamer.stream());
|
||||
// streamer.stream() << " ";
|
||||
// ShaveYakAndWriteToStreamPointer(yak3, &streamer.stream());
|
||||
// }
|
||||
class LogStreamer final {
|
||||
public:
|
||||
// LogStreamer::LogStreamer()
|
||||
//
|
||||
// Creates a LogStreamer with a given `severity` that will log a message
|
||||
// attributed to the given `file` and `line`.
|
||||
explicit LogStreamer(absl::LogSeverity severity, absl::string_view file,
|
||||
int line)
|
||||
: severity_(severity),
|
||||
line_(line),
|
||||
file_(file),
|
||||
stream_(absl::in_place, &buf_) {
|
||||
// To match `LOG`'s defaults:
|
||||
stream_->setf(std::ios_base::showbase | std::ios_base::boolalpha);
|
||||
}
|
||||
|
||||
// A moved-from `absl::LogStreamer` does not `LOG` when destroyed,
|
||||
// and a program that streams into one has undefined behavior.
|
||||
LogStreamer(LogStreamer&& that) noexcept
|
||||
: severity_(that.severity_),
|
||||
line_(that.line_),
|
||||
file_(std::move(that.file_)),
|
||||
buf_(std::move(that.buf_)),
|
||||
stream_(std::move(that.stream_)) {
|
||||
if (stream_.has_value()) stream_->str(&buf_);
|
||||
that.stream_.reset();
|
||||
}
|
||||
LogStreamer& operator=(LogStreamer&& that) {
|
||||
ABSL_LOG_IF(LEVEL(severity_), stream_).AtLocation(file_, line_) << buf_;
|
||||
severity_ = that.severity_;
|
||||
file_ = std::move(that.file_);
|
||||
line_ = that.line_;
|
||||
buf_ = std::move(that.buf_);
|
||||
stream_ = std::move(that.stream_);
|
||||
if (stream_.has_value()) stream_->str(&buf_);
|
||||
that.stream_.reset();
|
||||
return *this;
|
||||
}
|
||||
|
||||
// LogStreamer::~LogStreamer()
|
||||
//
|
||||
// Logs this LogStreamer's buffered content as if by LOG.
|
||||
~LogStreamer() {
|
||||
ABSL_LOG_IF(LEVEL(severity_), stream_.has_value()).AtLocation(file_, line_)
|
||||
<< buf_;
|
||||
}
|
||||
|
||||
// LogStreamer::stream()
|
||||
//
|
||||
// Returns the `std::ostream` to use to write into this LogStreamer' internal
|
||||
// buffer.
|
||||
std::ostream& stream() { return *stream_; }
|
||||
|
||||
private:
|
||||
absl::LogSeverity severity_;
|
||||
int line_;
|
||||
std::string file_;
|
||||
std::string buf_;
|
||||
// A disengaged `stream_` indicates a moved-from `LogStreamer` that should not
|
||||
// `LOG` upon destruction.
|
||||
absl::optional<absl::strings_internal::OStringStream> stream_;
|
||||
};
|
||||
|
||||
// LogInfoStreamer()
|
||||
//
|
||||
// Returns a LogStreamer that writes at level LogSeverity::kInfo.
|
||||
inline LogStreamer LogInfoStreamer(absl::string_view file, int line) {
|
||||
return absl::LogStreamer(absl::LogSeverity::kInfo, file, line);
|
||||
}
|
||||
|
||||
// LogWarningStreamer()
|
||||
//
|
||||
// Returns a LogStreamer that writes at level LogSeverity::kWarning.
|
||||
inline LogStreamer LogWarningStreamer(absl::string_view file, int line) {
|
||||
return absl::LogStreamer(absl::LogSeverity::kWarning, file, line);
|
||||
}
|
||||
|
||||
// LogErrorStreamer()
|
||||
//
|
||||
// Returns a LogStreamer that writes at level LogSeverity::kError.
|
||||
inline LogStreamer LogErrorStreamer(absl::string_view file, int line) {
|
||||
return absl::LogStreamer(absl::LogSeverity::kError, file, line);
|
||||
}
|
||||
|
||||
// LogFatalStreamer()
|
||||
//
|
||||
// Returns a LogStreamer that writes at level LogSeverity::kFatal.
|
||||
//
|
||||
// The program will be terminated when this `LogStreamer` is destroyed,
|
||||
// regardless of whether any data were streamed in.
|
||||
inline LogStreamer LogFatalStreamer(absl::string_view file, int line) {
|
||||
return absl::LogStreamer(absl::LogSeverity::kFatal, file, line);
|
||||
}
|
||||
|
||||
// LogDebugFatalStreamer()
|
||||
//
|
||||
// Returns a LogStreamer that writes at level LogSeverity::kLogDebugFatal.
|
||||
//
|
||||
// In debug mode, the program will be terminated when this `LogStreamer` is
|
||||
// destroyed, regardless of whether any data were streamed in.
|
||||
inline LogStreamer LogDebugFatalStreamer(absl::string_view file, int line) {
|
||||
return absl::LogStreamer(absl::kLogDebugFatal, file, line);
|
||||
}
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_LOG_STREAMER_H_
|
||||
438
TMessagesProj/jni/voip/webrtc/absl/log/log_streamer_test.cc
Normal file
438
TMessagesProj/jni/voip/webrtc/absl/log/log_streamer_test.cc
Normal file
|
|
@ -0,0 +1,438 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/log_streamer.h"
|
||||
|
||||
#include <ios>
|
||||
#include <iostream>
|
||||
#include <utility>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/internal/sysinfo.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/internal/test_actions.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace {
|
||||
using ::absl::log_internal::DeathTestExpectedLogging;
|
||||
using ::absl::log_internal::DeathTestUnexpectedLogging;
|
||||
using ::absl::log_internal::DeathTestValidateExpectations;
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
using ::absl::log_internal::DiedOfFatal;
|
||||
#endif
|
||||
using ::absl::log_internal::InMatchWindow;
|
||||
using ::absl::log_internal::LogSeverity;
|
||||
using ::absl::log_internal::Prefix;
|
||||
using ::absl::log_internal::SourceFilename;
|
||||
using ::absl::log_internal::SourceLine;
|
||||
using ::absl::log_internal::Stacktrace;
|
||||
using ::absl::log_internal::TextMessage;
|
||||
using ::absl::log_internal::ThreadID;
|
||||
using ::absl::log_internal::Timestamp;
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::Eq;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::IsEmpty;
|
||||
using ::testing::IsTrue;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
void WriteToStream(absl::string_view data, std::ostream* os) {
|
||||
*os << "WriteToStream: " << data;
|
||||
}
|
||||
void WriteToStreamRef(absl::string_view data, std::ostream& os) {
|
||||
os << "WriteToStreamRef: " << data;
|
||||
}
|
||||
|
||||
TEST(LogStreamerTest, LogInfoStreamer) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(
|
||||
AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kInfo)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::INFO), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream("foo", &absl::LogInfoStreamer("path/file.cc", 1234).stream());
|
||||
}
|
||||
|
||||
TEST(LogStreamerTest, LogWarningStreamer) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kWarning)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::WARNING), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream("foo",
|
||||
&absl::LogWarningStreamer("path/file.cc", 1234).stream());
|
||||
}
|
||||
|
||||
TEST(LogStreamerTest, LogErrorStreamer) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream("foo", &absl::LogErrorStreamer("path/file.cc", 1234).stream());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(LogStreamerDeathTest, LogFatalStreamer) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream("foo",
|
||||
&absl::LogFatalStreamer("path/file.cc", 1234).stream());
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
TEST(LogStreamerTest, LogDebugFatalStreamer) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream("foo",
|
||||
&absl::LogDebugFatalStreamer("path/file.cc", 1234).stream());
|
||||
}
|
||||
#elif GTEST_HAS_DEATH_TEST
|
||||
TEST(LogStreamerDeathTest, LogDebugFatalStreamer) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream(
|
||||
"foo", &absl::LogDebugFatalStreamer("path/file.cc", 1234).stream());
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(LogStreamerTest, LogStreamer) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kError)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::ERROR), Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream(
|
||||
"foo", &absl::LogStreamer(absl::LogSeverity::kError, "path/file.cc", 1234)
|
||||
.stream());
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(LogStreamerDeathTest, LogStreamer) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
|
||||
EXPECT_CALL(test_sink, Send)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
Prefix(IsTrue()), LogSeverity(Eq(absl::LogSeverity::kFatal)),
|
||||
Timestamp(InMatchWindow()),
|
||||
ThreadID(Eq(absl::base_internal::GetTID())),
|
||||
TextMessage(Eq("WriteToStream: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), InMatchWindow(),
|
||||
Eq(logging::proto::FATAL),
|
||||
Eq(absl::base_internal::GetTID()),
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStream: foo"))))))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStream("foo", &absl::LogStreamer(absl::LogSeverity::kFatal,
|
||||
"path/file.cc", 1234)
|
||||
.stream());
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(LogStreamerTest, PassedByReference) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
TextMessage(Eq("WriteToStreamRef: foo")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), _, _, _,
|
||||
ElementsAre(ValueWithStr(Eq("WriteToStreamRef: foo"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
WriteToStreamRef("foo", absl::LogInfoStreamer("path/file.cc", 1234).stream());
|
||||
}
|
||||
|
||||
TEST(LogStreamerTest, StoredAsLocal) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
auto streamer = absl::LogInfoStreamer("path/file.cc", 1234);
|
||||
WriteToStream("foo", &streamer.stream());
|
||||
streamer.stream() << " ";
|
||||
WriteToStreamRef("bar", streamer.stream());
|
||||
|
||||
// The call should happen when `streamer` goes out of scope; if it
|
||||
// happened before this `EXPECT_CALL` the call would be unexpected and the
|
||||
// test would fail.
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
TextMessage(Eq("WriteToStream: foo WriteToStreamRef: bar")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), _, _, _,
|
||||
ElementsAre(ValueWithStr(
|
||||
Eq("WriteToStream: foo WriteToStreamRef: bar"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(LogStreamerDeathTest, StoredAsLocal) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
// This is fatal when it goes out of scope, but not until then:
|
||||
auto streamer = absl::LogFatalStreamer("path/file.cc", 1234);
|
||||
std::cerr << "I'm still alive" << std::endl;
|
||||
WriteToStream("foo", &streamer.stream());
|
||||
},
|
||||
DiedOfFatal, HasSubstr("I'm still alive"));
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(LogStreamerTest, LogsEmptyLine) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(test_sink, Send(AllOf(SourceFilename(Eq("path/file.cc")),
|
||||
SourceLine(Eq(1234)), TextMessage(Eq("")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), _, _, _,
|
||||
ElementsAre(ValueWithStr(Eq(""))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::LogInfoStreamer("path/file.cc", 1234);
|
||||
}
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(LogStreamerDeathTest, LogsEmptyLine) {
|
||||
EXPECT_EXIT(
|
||||
{
|
||||
absl::ScopedMockLog test_sink;
|
||||
|
||||
EXPECT_CALL(test_sink, Log)
|
||||
.Times(AnyNumber())
|
||||
.WillRepeatedly(DeathTestUnexpectedLogging());
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(SourceFilename(Eq("path/file.cc")), TextMessage(Eq("")),
|
||||
ENCODED_MESSAGE(
|
||||
MatchesEvent(Eq("path/file.cc"), _, _, _, _,
|
||||
ElementsAre(ValueWithStr(Eq(""))))))))
|
||||
.WillOnce(DeathTestExpectedLogging());
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
// This is fatal even though it's never used:
|
||||
auto streamer = absl::LogFatalStreamer("path/file.cc", 1234);
|
||||
},
|
||||
DiedOfFatal, DeathTestValidateExpectations());
|
||||
}
|
||||
#endif
|
||||
|
||||
TEST(LogStreamerTest, MoveConstruction) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(
|
||||
AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
LogSeverity(Eq(absl::LogSeverity::kInfo)),
|
||||
TextMessage(Eq("hello 0x10 world 0x10")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), _, Eq(logging::proto::INFO),
|
||||
_, ElementsAre(ValueWithStr(Eq("hello 0x10 world 0x10"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
auto streamer1 = absl::LogInfoStreamer("path/file.cc", 1234);
|
||||
streamer1.stream() << "hello " << std::hex << 16;
|
||||
absl::LogStreamer streamer2(std::move(streamer1));
|
||||
streamer2.stream() << " world " << 16;
|
||||
}
|
||||
|
||||
TEST(LogStreamerTest, MoveAssignment) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
testing::InSequence seq;
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(AllOf(
|
||||
SourceFilename(Eq("path/file2.cc")), SourceLine(Eq(5678)),
|
||||
LogSeverity(Eq(absl::LogSeverity::kWarning)),
|
||||
TextMessage(Eq("something else")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file2.cc"), Eq(5678), _, Eq(logging::proto::WARNING), _,
|
||||
ElementsAre(ValueWithStr(Eq("something else"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
EXPECT_CALL(
|
||||
test_sink,
|
||||
Send(
|
||||
AllOf(SourceFilename(Eq("path/file.cc")), SourceLine(Eq(1234)),
|
||||
LogSeverity(Eq(absl::LogSeverity::kInfo)),
|
||||
TextMessage(Eq("hello 0x10 world 0x10")),
|
||||
ENCODED_MESSAGE(MatchesEvent(
|
||||
Eq("path/file.cc"), Eq(1234), _, Eq(logging::proto::INFO),
|
||||
_, ElementsAre(ValueWithStr(Eq("hello 0x10 world 0x10"))))),
|
||||
Stacktrace(IsEmpty()))));
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
auto streamer1 = absl::LogInfoStreamer("path/file.cc", 1234);
|
||||
streamer1.stream() << "hello " << std::hex << 16;
|
||||
auto streamer2 = absl::LogWarningStreamer("path/file2.cc", 5678);
|
||||
streamer2.stream() << "something else";
|
||||
streamer2 = std::move(streamer1);
|
||||
streamer2.stream() << " world " << 16;
|
||||
}
|
||||
|
||||
TEST(LogStreamerTest, CorrectDefaultFlags) {
|
||||
absl::ScopedMockLog test_sink(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
// The `boolalpha` and `showbase` flags should be set by default, to match
|
||||
// `LOG`.
|
||||
EXPECT_CALL(test_sink, Send(AllOf(TextMessage(Eq("false0xdeadbeef")))))
|
||||
.Times(2);
|
||||
|
||||
test_sink.StartCapturingLogs();
|
||||
absl::LogInfoStreamer("path/file.cc", 1234).stream()
|
||||
<< false << std::hex << 0xdeadbeef;
|
||||
LOG(INFO) << false << std::hex << 0xdeadbeef;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
86
TMessagesProj/jni/voip/webrtc/absl/log/scoped_mock_log.cc
Normal file
86
TMessagesProj/jni/voip/webrtc/absl/log/scoped_mock_log.cc
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/internal/raw_logging.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
#include "absl/log/log_sink_registry.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
ScopedMockLog::ScopedMockLog(MockLogDefault default_exp)
|
||||
: sink_(this), is_capturing_logs_(false), is_triggered_(false) {
|
||||
if (default_exp == MockLogDefault::kIgnoreUnexpected) {
|
||||
// Ignore all calls to Log we did not set expectations for.
|
||||
EXPECT_CALL(*this, Log).Times(::testing::AnyNumber());
|
||||
} else {
|
||||
// Disallow all calls to Log we did not set expectations for.
|
||||
EXPECT_CALL(*this, Log).Times(0);
|
||||
}
|
||||
// By default Send mock forwards to Log mock.
|
||||
EXPECT_CALL(*this, Send)
|
||||
.Times(::testing::AnyNumber())
|
||||
.WillRepeatedly([this](const absl::LogEntry& entry) {
|
||||
is_triggered_.store(true, std::memory_order_relaxed);
|
||||
Log(entry.log_severity(), std::string(entry.source_filename()),
|
||||
std::string(entry.text_message()));
|
||||
});
|
||||
|
||||
// By default We ignore all Flush calls.
|
||||
EXPECT_CALL(*this, Flush).Times(::testing::AnyNumber());
|
||||
}
|
||||
|
||||
ScopedMockLog::~ScopedMockLog() {
|
||||
ABSL_RAW_CHECK(is_triggered_.load(std::memory_order_relaxed),
|
||||
"Did you forget to call StartCapturingLogs()?");
|
||||
|
||||
if (is_capturing_logs_) StopCapturingLogs();
|
||||
}
|
||||
|
||||
void ScopedMockLog::StartCapturingLogs() {
|
||||
ABSL_RAW_CHECK(!is_capturing_logs_,
|
||||
"StartCapturingLogs() can be called only when the "
|
||||
"absl::ScopedMockLog object is not capturing logs.");
|
||||
|
||||
is_capturing_logs_ = true;
|
||||
is_triggered_.store(true, std::memory_order_relaxed);
|
||||
absl::AddLogSink(&sink_);
|
||||
}
|
||||
|
||||
void ScopedMockLog::StopCapturingLogs() {
|
||||
ABSL_RAW_CHECK(is_capturing_logs_,
|
||||
"StopCapturingLogs() can be called only when the "
|
||||
"absl::ScopedMockLog object is capturing logs.");
|
||||
|
||||
is_capturing_logs_ = false;
|
||||
absl::RemoveLogSink(&sink_);
|
||||
}
|
||||
|
||||
absl::LogSink& ScopedMockLog::UseAsLocalSink() {
|
||||
is_triggered_.store(true, std::memory_order_relaxed);
|
||||
return sink_;
|
||||
}
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
197
TMessagesProj/jni/voip/webrtc/absl/log/scoped_mock_log.h
Normal file
197
TMessagesProj/jni/voip/webrtc/absl/log/scoped_mock_log.h
Normal file
|
|
@ -0,0 +1,197 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/scoped_mock_log.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares `class absl::ScopedMockLog`, for use in testing.
|
||||
|
||||
#ifndef ABSL_LOG_SCOPED_MOCK_LOG_H_
|
||||
#define ABSL_LOG_SCOPED_MOCK_LOG_H_
|
||||
|
||||
#include <atomic>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/log_entry.h"
|
||||
#include "absl/log/log_sink.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// MockLogDefault
|
||||
//
|
||||
// Controls how ScopedMockLog responds to unexpected calls by default.
|
||||
enum class MockLogDefault { kIgnoreUnexpected, kDisallowUnexpected };
|
||||
|
||||
// ScopedMockLog
|
||||
//
|
||||
// ScopedMockLog is a LogSink that intercepts LOG() messages issued by all
|
||||
// threads when active.
|
||||
//
|
||||
// Using this together with GoogleTest, it's easy to test how a piece of code
|
||||
// calls LOG(). The typical usage, noting the distinction between
|
||||
// "uninteresting" and "unexpected", looks like this:
|
||||
//
|
||||
// using ::testing::_;
|
||||
// using ::testing::AnyNumber;
|
||||
// using ::testing::EndsWith;
|
||||
// using ::testing::kDoNotCaptureLogsYet;
|
||||
// using ::testing::Lt;
|
||||
//
|
||||
// TEST(FooTest, LogsCorrectly) {
|
||||
// // Simple robust setup, ignores unexpected logs.
|
||||
// absl::ScopedMockLog log;
|
||||
//
|
||||
// // We expect the WARNING "Something bad!" exactly twice.
|
||||
// EXPECT_CALL(log, Log(absl::LogSeverity::kWarning, _, "Something bad!"))
|
||||
// .Times(2);
|
||||
//
|
||||
// // But we want no messages from foo.cc.
|
||||
// EXPECT_CALL(log, Log(_, EndsWith("/foo.cc"), _)).Times(0);
|
||||
//
|
||||
// log.StartCapturingLogs(); // Call this after done setting expectations.
|
||||
// Foo(); // Exercises the code under test.
|
||||
// }
|
||||
//
|
||||
// TEST(BarTest, LogsExactlyCorrectly) {
|
||||
// // Strict checking, fails for unexpected logs.
|
||||
// absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
//
|
||||
// // ... but ignore low severity messages
|
||||
// EXPECT_CALL(log, Log(Lt(absl::LogSeverity::kWarning), _, _))
|
||||
// .Times(AnyNumber());
|
||||
//
|
||||
// // We expect the ERROR "Something bad!" exactly once.
|
||||
// EXPECT_CALL(log, Log(absl::LogSeverity::kError, EndsWith("/foo.cc"),
|
||||
// "Something bad!"))
|
||||
// .Times(1);
|
||||
//
|
||||
// log.StartCapturingLogs(); // Call this after done setting expectations.
|
||||
// Bar(); // Exercises the code under test.
|
||||
// }
|
||||
//
|
||||
// Note that in a multi-threaded environment, all LOG() messages from a single
|
||||
// thread will be handled in sequence, but that cannot be guaranteed for
|
||||
// messages from different threads. In fact, if the same or multiple
|
||||
// expectations are matched on two threads concurrently, their actions will be
|
||||
// executed concurrently as well and may interleave.
|
||||
class ScopedMockLog final {
|
||||
public:
|
||||
// ScopedMockLog::ScopedMockLog()
|
||||
//
|
||||
// Sets up the log and adds default expectations.
|
||||
explicit ScopedMockLog(
|
||||
MockLogDefault default_exp = MockLogDefault::kIgnoreUnexpected);
|
||||
ScopedMockLog(const ScopedMockLog&) = delete;
|
||||
ScopedMockLog& operator=(const ScopedMockLog&) = delete;
|
||||
|
||||
// ScopedMockLog::~ScopedMockLog()
|
||||
//
|
||||
// Stops intercepting logs and destroys this ScopedMockLog.
|
||||
~ScopedMockLog();
|
||||
|
||||
// ScopedMockLog::StartCapturingLogs()
|
||||
//
|
||||
// Starts log capturing if the object isn't already doing so. Otherwise
|
||||
// crashes.
|
||||
//
|
||||
// Usually this method is called in the same thread that created this
|
||||
// ScopedMockLog. It is the user's responsibility to not call this method if
|
||||
// another thread may be calling it or StopCapturingLogs() at the same time.
|
||||
// It is undefined behavior to add expectations while capturing logs is
|
||||
// enabled.
|
||||
void StartCapturingLogs();
|
||||
|
||||
// ScopedMockLog::StopCapturingLogs()
|
||||
//
|
||||
// Stops log capturing if the object is capturing logs. Otherwise crashes.
|
||||
//
|
||||
// Usually this method is called in the same thread that created this object.
|
||||
// It is the user's responsibility to not call this method if another thread
|
||||
// may be calling it or StartCapturingLogs() at the same time.
|
||||
//
|
||||
// It is UB to add expectations, while capturing logs is enabled.
|
||||
void StopCapturingLogs();
|
||||
|
||||
// ScopedMockLog::UseAsLocalSink()
|
||||
//
|
||||
// Each `ScopedMockLog` is implemented with an `absl::LogSink`; this method
|
||||
// returns a reference to that sink (e.g. for use with
|
||||
// `LOG(...).ToSinkOnly()`) and marks the `ScopedMockLog` as having been used
|
||||
// even if `StartCapturingLogs` is never called.
|
||||
absl::LogSink& UseAsLocalSink();
|
||||
|
||||
// Implements the mock method:
|
||||
//
|
||||
// void Log(LogSeverity severity, absl::string_view file_path,
|
||||
// absl::string_view message);
|
||||
//
|
||||
// The second argument to Log() is the full path of the source file in
|
||||
// which the LOG() was issued.
|
||||
//
|
||||
// This is a shorthand form, which should be used by most users. Use the
|
||||
// `Send` mock only if you want to add expectations for other log message
|
||||
// attributes.
|
||||
MOCK_METHOD(void, Log,
|
||||
(absl::LogSeverity severity, const std::string& file_path,
|
||||
const std::string& message));
|
||||
|
||||
// Implements the mock method:
|
||||
//
|
||||
// void Send(const absl::LogEntry& entry);
|
||||
//
|
||||
// This is the most generic form of mock that can be specified. Use this mock
|
||||
// only if you want to add expectations for log message attributes different
|
||||
// from the log message text, log message path and log message severity.
|
||||
//
|
||||
// If no expectations are specified for this mock, the default action is to
|
||||
// forward the call to the `Log` mock.
|
||||
MOCK_METHOD(void, Send, (const absl::LogEntry&));
|
||||
|
||||
// Implements the mock method:
|
||||
//
|
||||
// void Flush();
|
||||
//
|
||||
// Use this mock only if you want to add expectations for log flush calls.
|
||||
MOCK_METHOD(void, Flush, ());
|
||||
|
||||
private:
|
||||
class ForwardingSink final : public absl::LogSink {
|
||||
public:
|
||||
explicit ForwardingSink(ScopedMockLog* sml) : sml_(sml) {}
|
||||
ForwardingSink(const ForwardingSink&) = delete;
|
||||
ForwardingSink& operator=(const ForwardingSink&) = delete;
|
||||
void Send(const absl::LogEntry& entry) override { sml_->Send(entry); }
|
||||
void Flush() override { sml_->Flush(); }
|
||||
|
||||
private:
|
||||
ScopedMockLog* sml_;
|
||||
};
|
||||
|
||||
ForwardingSink sink_;
|
||||
bool is_capturing_logs_;
|
||||
// Until C++20, the default constructor leaves the underlying value wrapped in
|
||||
// std::atomic uninitialized, so all constructors should be sure to initialize
|
||||
// is_triggered_.
|
||||
std::atomic<bool> is_triggered_;
|
||||
};
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_SCOPED_MOCK_LOG_H_
|
||||
295
TMessagesProj/jni/voip/webrtc/absl/log/scoped_mock_log_test.cc
Normal file
295
TMessagesProj/jni/voip/webrtc/absl/log/scoped_mock_log_test.cc
Normal file
|
|
@ -0,0 +1,295 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
|
||||
#include <memory>
|
||||
#include <thread> // NOLINT(build/c++11)
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest-spi.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/memory/memory.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
#include "absl/synchronization/barrier.h"
|
||||
#include "absl/synchronization/notification.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::_;
|
||||
using ::testing::AnyNumber;
|
||||
using ::testing::Eq;
|
||||
using ::testing::HasSubstr;
|
||||
using ::testing::InSequence;
|
||||
using ::testing::Lt;
|
||||
using ::testing::Truly;
|
||||
using absl::log_internal::SourceBasename;
|
||||
using absl::log_internal::SourceFilename;
|
||||
using absl::log_internal::SourceLine;
|
||||
using absl::log_internal::TextMessageWithPrefix;
|
||||
using absl::log_internal::ThreadID;
|
||||
|
||||
auto* test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
#if GTEST_HAS_DEATH_TEST
|
||||
TEST(ScopedMockLogDeathTest,
|
||||
StartCapturingLogsCannotBeCalledWhenAlreadyCapturing) {
|
||||
EXPECT_DEATH(
|
||||
{
|
||||
absl::ScopedMockLog log;
|
||||
log.StartCapturingLogs();
|
||||
log.StartCapturingLogs();
|
||||
},
|
||||
"StartCapturingLogs");
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogDeathTest, StopCapturingLogsCannotBeCalledWhenNotCapturing) {
|
||||
EXPECT_DEATH(
|
||||
{
|
||||
absl::ScopedMockLog log;
|
||||
log.StopCapturingLogs();
|
||||
},
|
||||
"StopCapturingLogs");
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogDeathTest, FailsCheckIfStartCapturingLogsIsNeverCalled) {
|
||||
EXPECT_DEATH({ absl::ScopedMockLog log; },
|
||||
"Did you forget to call StartCapturingLogs");
|
||||
}
|
||||
#endif
|
||||
|
||||
// Tests that ScopedMockLog intercepts LOG()s when it's alive.
|
||||
TEST(ScopedMockLogTest, LogMockCatchAndMatchStrictExpectations) {
|
||||
absl::ScopedMockLog log;
|
||||
|
||||
// The following expectations must match in the order they appear.
|
||||
InSequence s;
|
||||
EXPECT_CALL(log,
|
||||
Log(absl::LogSeverity::kWarning, HasSubstr(__FILE__), "Danger."));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "Working...")).Times(2);
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, _, "Bad!!"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
LOG(WARNING) << "Danger.";
|
||||
LOG(INFO) << "Working...";
|
||||
LOG(INFO) << "Working...";
|
||||
LOG(ERROR) << "Bad!!";
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogTest, LogMockCatchAndMatchSendExpectations) {
|
||||
absl::ScopedMockLog log;
|
||||
|
||||
EXPECT_CALL(
|
||||
log,
|
||||
Send(AllOf(SourceFilename(Eq("/my/very/very/very_long_source_file.cc")),
|
||||
SourceBasename(Eq("very_long_source_file.cc")),
|
||||
SourceLine(Eq(777)), ThreadID(Eq(absl::LogEntry::tid_t{1234})),
|
||||
TextMessageWithPrefix(Truly([](absl::string_view msg) {
|
||||
return absl::EndsWith(
|
||||
msg, " very_long_source_file.cc:777] Info message");
|
||||
})))));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
LOG(INFO)
|
||||
.AtLocation("/my/very/very/very_long_source_file.cc", 777)
|
||||
.WithThreadID(1234)
|
||||
<< "Info message";
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogTest, ScopedMockLogCanBeNice) {
|
||||
absl::ScopedMockLog log;
|
||||
|
||||
InSequence s;
|
||||
EXPECT_CALL(log,
|
||||
Log(absl::LogSeverity::kWarning, HasSubstr(__FILE__), "Danger."));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "Working...")).Times(2);
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kError, _, "Bad!!"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
|
||||
// Any number of these are OK.
|
||||
LOG(INFO) << "Info message.";
|
||||
// Any number of these are OK.
|
||||
LOG(WARNING).AtLocation("SomeOtherFile.cc", 100) << "Danger ";
|
||||
|
||||
LOG(WARNING) << "Danger.";
|
||||
|
||||
// Any number of these are OK.
|
||||
LOG(INFO) << "Info message.";
|
||||
// Any number of these are OK.
|
||||
LOG(WARNING).AtLocation("SomeOtherFile.cc", 100) << "Danger ";
|
||||
|
||||
LOG(INFO) << "Working...";
|
||||
|
||||
// Any number of these are OK.
|
||||
LOG(INFO) << "Info message.";
|
||||
// Any number of these are OK.
|
||||
LOG(WARNING).AtLocation("SomeOtherFile.cc", 100) << "Danger ";
|
||||
|
||||
LOG(INFO) << "Working...";
|
||||
|
||||
// Any number of these are OK.
|
||||
LOG(INFO) << "Info message.";
|
||||
// Any number of these are OK.
|
||||
LOG(WARNING).AtLocation("SomeOtherFile.cc", 100) << "Danger ";
|
||||
|
||||
LOG(ERROR) << "Bad!!";
|
||||
|
||||
// Any number of these are OK.
|
||||
LOG(INFO) << "Info message.";
|
||||
// Any number of these are OK.
|
||||
LOG(WARNING).AtLocation("SomeOtherFile.cc", 100) << "Danger ";
|
||||
}
|
||||
|
||||
// Tests that ScopedMockLog generates a test failure if a message is logged
|
||||
// that is not expected (here, that means ERROR or FATAL).
|
||||
TEST(ScopedMockLogTest, RejectsUnexpectedLogs) {
|
||||
EXPECT_NONFATAL_FAILURE(
|
||||
{
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
// Any INFO and WARNING messages are permitted.
|
||||
EXPECT_CALL(log, Log(Lt(absl::LogSeverity::kError), _, _))
|
||||
.Times(AnyNumber());
|
||||
log.StartCapturingLogs();
|
||||
LOG(INFO) << "Ignored";
|
||||
LOG(WARNING) << "Ignored";
|
||||
LOG(ERROR) << "Should not be ignored";
|
||||
},
|
||||
"Should not be ignored");
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogTest, CapturesLogsAfterStartCapturingLogs) {
|
||||
absl::SetStderrThreshold(absl::LogSeverityAtLeast::kInfinity);
|
||||
absl::ScopedMockLog log;
|
||||
|
||||
// The ScopedMockLog object shouldn't see these LOGs, as it hasn't
|
||||
// started capturing LOGs yet.
|
||||
LOG(INFO) << "Ignored info";
|
||||
LOG(WARNING) << "Ignored warning";
|
||||
LOG(ERROR) << "Ignored error";
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "Expected info"));
|
||||
log.StartCapturingLogs();
|
||||
|
||||
// Only this LOG will be seen by the ScopedMockLog.
|
||||
LOG(INFO) << "Expected info";
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogTest, DoesNotCaptureLogsAfterStopCapturingLogs) {
|
||||
absl::ScopedMockLog log;
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "Expected info"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
|
||||
// This LOG should be seen by the ScopedMockLog.
|
||||
LOG(INFO) << "Expected info";
|
||||
|
||||
log.StopCapturingLogs();
|
||||
|
||||
// The ScopedMockLog object shouldn't see these LOGs, as it has
|
||||
// stopped capturing LOGs.
|
||||
LOG(INFO) << "Ignored info";
|
||||
LOG(WARNING) << "Ignored warning";
|
||||
LOG(ERROR) << "Ignored error";
|
||||
}
|
||||
|
||||
// Tests that all messages are intercepted regardless of issuing thread. The
|
||||
// purpose of this test is NOT to exercise thread-safety.
|
||||
TEST(ScopedMockLogTest, LogFromMultipleThreads) {
|
||||
absl::ScopedMockLog log;
|
||||
|
||||
// We don't establish an order to expectations here, since the threads may
|
||||
// execute their log statements in different order.
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, __FILE__, "Thread 1"));
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, __FILE__, "Thread 2"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
|
||||
absl::Barrier barrier(2);
|
||||
std::thread thread1([&barrier]() {
|
||||
barrier.Block();
|
||||
LOG(INFO) << "Thread 1";
|
||||
});
|
||||
std::thread thread2([&barrier]() {
|
||||
barrier.Block();
|
||||
LOG(INFO) << "Thread 2";
|
||||
});
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
|
||||
// Tests that no sequence will be imposed on two LOG message expectations from
|
||||
// different threads. This test would actually deadlock if replaced to two LOG
|
||||
// statements from the same thread.
|
||||
TEST(ScopedMockLogTest, NoSequenceWithMultipleThreads) {
|
||||
absl::ScopedMockLog log;
|
||||
|
||||
absl::Barrier barrier(2);
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, _))
|
||||
.Times(2)
|
||||
.WillRepeatedly([&barrier]() { barrier.Block(); });
|
||||
|
||||
log.StartCapturingLogs();
|
||||
|
||||
std::thread thread1([]() { LOG(INFO) << "Thread 1"; });
|
||||
std::thread thread2([]() { LOG(INFO) << "Thread 2"; });
|
||||
|
||||
thread1.join();
|
||||
thread2.join();
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogTsanTest,
|
||||
ScopedMockLogCanBeDeletedWhenAnotherThreadIsLogging) {
|
||||
auto log = absl::make_unique<absl::ScopedMockLog>();
|
||||
EXPECT_CALL(*log, Log(absl::LogSeverity::kInfo, __FILE__, "Thread log"))
|
||||
.Times(AnyNumber());
|
||||
|
||||
log->StartCapturingLogs();
|
||||
|
||||
absl::Notification logging_started;
|
||||
|
||||
std::thread thread([&logging_started]() {
|
||||
for (int i = 0; i < 100; ++i) {
|
||||
if (i == 50) logging_started.Notify();
|
||||
LOG(INFO) << "Thread log";
|
||||
}
|
||||
});
|
||||
|
||||
logging_started.WaitForNotification();
|
||||
log.reset();
|
||||
thread.join();
|
||||
}
|
||||
|
||||
TEST(ScopedMockLogTest, AsLocalSink) {
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(_, _, "two"));
|
||||
EXPECT_CALL(log, Log(_, _, "three"));
|
||||
|
||||
LOG(INFO) << "one";
|
||||
LOG(INFO).ToSinkOnly(&log.UseAsLocalSink()) << "two";
|
||||
LOG(INFO).ToSinkAlso(&log.UseAsLocalSink()) << "three";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
502
TMessagesProj/jni/voip/webrtc/absl/log/stripping_test.cc
Normal file
502
TMessagesProj/jni/voip/webrtc/absl/log/stripping_test.cc
Normal file
|
|
@ -0,0 +1,502 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// Tests for stripping of literal strings.
|
||||
// ---------------------------------------
|
||||
//
|
||||
// When a `LOG` statement can be trivially proved at compile time to never fire,
|
||||
// e.g. due to `ABSL_MIN_LOG_LEVEL`, `NDEBUG`, or some explicit condition, data
|
||||
// streamed in can be dropped from the compiled program completely if they are
|
||||
// not used elsewhere. This most commonly affects string literals, which users
|
||||
// often want to strip to reduce binary size and/or redact information about
|
||||
// their program's internals (e.g. in a release build).
|
||||
//
|
||||
// These tests log strings and then validate whether they appear in the compiled
|
||||
// binary. This is done by opening the file corresponding to the running test
|
||||
// and running a simple string search on its contents. The strings to be logged
|
||||
// and searched for must be unique, and we must take care not to emit them into
|
||||
// the binary in any other place, e.g. when searching for them. The latter is
|
||||
// accomplished by computing them using base64; the source string appears in the
|
||||
// binary but the target string is computed at runtime.
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#if defined(__MACH__)
|
||||
#include <mach-o/dyld.h>
|
||||
#elif defined(_WIN32)
|
||||
#include <Windows.h>
|
||||
#include <tchar.h>
|
||||
#endif
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/internal/strerror.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/flags/internal/program_name.h"
|
||||
#include "absl/log/check.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/status/status.h"
|
||||
#include "absl/strings/escaping.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
// Set a flag that controls whether we actually execute fatal statements, but
|
||||
// prevent the compiler from optimizing it out.
|
||||
static volatile bool kReallyDie = false;
|
||||
|
||||
namespace {
|
||||
using ::testing::_;
|
||||
using ::testing::Eq;
|
||||
using ::testing::NotNull;
|
||||
|
||||
using absl::log_internal::kAbslMinLogLevel;
|
||||
|
||||
std::string Base64UnescapeOrDie(absl::string_view data) {
|
||||
std::string decoded;
|
||||
CHECK(absl::Base64Unescape(data, &decoded));
|
||||
return decoded;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// A Googletest matcher which searches the running binary for a given string
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// This matcher is used to validate that literal strings streamed into
|
||||
// `LOG` statements that ought to be compiled out (e.g. `LOG_IF(INFO, false)`)
|
||||
// do not appear in the binary.
|
||||
//
|
||||
// Note that passing the string to be sought directly to `FileHasSubstr()` all
|
||||
// but forces its inclusion in the binary regardless of the logging library's
|
||||
// behavior. For example:
|
||||
//
|
||||
// LOG_IF(INFO, false) << "you're the man now dog";
|
||||
// // This will always pass:
|
||||
// // EXPECT_THAT(fp, FileHasSubstr("you're the man now dog"));
|
||||
// // So use this instead:
|
||||
// EXPECT_THAT(fp, FileHasSubstr(
|
||||
// Base64UnescapeOrDie("eW91J3JlIHRoZSBtYW4gbm93IGRvZw==")));
|
||||
|
||||
class FileHasSubstrMatcher final : public ::testing::MatcherInterface<FILE*> {
|
||||
public:
|
||||
explicit FileHasSubstrMatcher(absl::string_view needle) : needle_(needle) {}
|
||||
|
||||
bool MatchAndExplain(
|
||||
FILE* fp, ::testing::MatchResultListener* listener) const override {
|
||||
std::string buf(
|
||||
std::max<std::string::size_type>(needle_.size() * 2, 163840000), '\0');
|
||||
size_t buf_start_offset = 0; // The file offset of the byte at `buf[0]`.
|
||||
size_t buf_data_size = 0; // The number of bytes of `buf` which contain
|
||||
// data.
|
||||
|
||||
::fseek(fp, 0, SEEK_SET);
|
||||
while (true) {
|
||||
// Fill the buffer to capacity or EOF:
|
||||
while (buf_data_size < buf.size()) {
|
||||
const size_t ret = fread(&buf[buf_data_size], sizeof(char),
|
||||
buf.size() - buf_data_size, fp);
|
||||
if (ret == 0) break;
|
||||
buf_data_size += ret;
|
||||
}
|
||||
if (ferror(fp)) {
|
||||
*listener << "error reading file";
|
||||
return false;
|
||||
}
|
||||
const absl::string_view haystack(&buf[0], buf_data_size);
|
||||
const auto off = haystack.find(needle_);
|
||||
if (off != haystack.npos) {
|
||||
*listener << "string found at offset " << buf_start_offset + off;
|
||||
return true;
|
||||
}
|
||||
if (feof(fp)) {
|
||||
*listener << "string not found";
|
||||
return false;
|
||||
}
|
||||
// Copy the end of `buf` to the beginning so we catch matches that span
|
||||
// buffer boundaries. `buf` and `buf_data_size` are always large enough
|
||||
// that these ranges don't overlap.
|
||||
memcpy(&buf[0], &buf[buf_data_size - needle_.size()], needle_.size());
|
||||
buf_start_offset += buf_data_size - needle_.size();
|
||||
buf_data_size = needle_.size();
|
||||
}
|
||||
}
|
||||
void DescribeTo(std::ostream* os) const override {
|
||||
*os << "contains the string \"" << needle_ << "\" (base64(\""
|
||||
<< Base64UnescapeOrDie(needle_) << "\"))";
|
||||
}
|
||||
|
||||
void DescribeNegationTo(std::ostream* os) const override {
|
||||
*os << "does not ";
|
||||
DescribeTo(os);
|
||||
}
|
||||
|
||||
private:
|
||||
std::string needle_;
|
||||
};
|
||||
|
||||
class StrippingTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override {
|
||||
#ifndef NDEBUG
|
||||
// Non-optimized builds don't necessarily eliminate dead code at all, so we
|
||||
// don't attempt to validate stripping against such builds.
|
||||
GTEST_SKIP() << "StrippingTests skipped since this build is not optimized";
|
||||
#elif defined(__EMSCRIPTEN__)
|
||||
// These tests require a way to examine the running binary and look for
|
||||
// strings; there's no portable way to do that.
|
||||
GTEST_SKIP()
|
||||
<< "StrippingTests skipped since this platform is not optimized";
|
||||
#endif
|
||||
}
|
||||
|
||||
// Opens this program's executable file. Returns `nullptr` and writes to
|
||||
// `stderr` on failure.
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> OpenTestExecutable() {
|
||||
#if defined(__linux__)
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> fp(
|
||||
fopen("/proc/self/exe", "rb"), [](FILE* fp) { fclose(fp); });
|
||||
if (!fp) {
|
||||
const std::string err = absl::base_internal::StrError(errno);
|
||||
absl::FPrintF(stderr, "Failed to open /proc/self/exe: %s\n", err);
|
||||
}
|
||||
return fp;
|
||||
#elif defined(__Fuchsia__)
|
||||
// TODO(b/242579714): We need to restore the test coverage on this platform.
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> fp(
|
||||
fopen(absl::StrCat("/pkg/bin/",
|
||||
absl::flags_internal::ShortProgramInvocationName())
|
||||
.c_str(),
|
||||
"rb"),
|
||||
[](FILE* fp) { fclose(fp); });
|
||||
if (!fp) {
|
||||
const std::string err = absl::base_internal::StrError(errno);
|
||||
absl::FPrintF(stderr, "Failed to open /pkg/bin/<binary name>: %s\n", err);
|
||||
}
|
||||
return fp;
|
||||
#elif defined(__MACH__)
|
||||
uint32_t size = 0;
|
||||
int ret = _NSGetExecutablePath(nullptr, &size);
|
||||
if (ret != -1) {
|
||||
absl::FPrintF(stderr,
|
||||
"Failed to get executable path: "
|
||||
"_NSGetExecutablePath(nullptr) returned %d\n",
|
||||
ret);
|
||||
return nullptr;
|
||||
}
|
||||
std::string path(size, '\0');
|
||||
ret = _NSGetExecutablePath(&path[0], &size);
|
||||
if (ret != 0) {
|
||||
absl::FPrintF(
|
||||
stderr,
|
||||
"Failed to get executable path: _NSGetExecutablePath(buffer) "
|
||||
"returned %d\n",
|
||||
ret);
|
||||
return nullptr;
|
||||
}
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> fp(
|
||||
fopen(path.c_str(), "rb"), [](FILE* fp) { fclose(fp); });
|
||||
if (!fp) {
|
||||
const std::string err = absl::base_internal::StrError(errno);
|
||||
absl::FPrintF(stderr, "Failed to open executable at %s: %s\n", path, err);
|
||||
}
|
||||
return fp;
|
||||
#elif defined(_WIN32)
|
||||
std::basic_string<TCHAR> path(4096, _T('\0'));
|
||||
while (true) {
|
||||
const uint32_t ret = ::GetModuleFileName(nullptr, &path[0],
|
||||
static_cast<DWORD>(path.size()));
|
||||
if (ret == 0) {
|
||||
absl::FPrintF(
|
||||
stderr,
|
||||
"Failed to get executable path: GetModuleFileName(buffer) "
|
||||
"returned 0\n");
|
||||
return nullptr;
|
||||
}
|
||||
if (ret < path.size()) break;
|
||||
path.resize(path.size() * 2, _T('\0'));
|
||||
}
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> fp(
|
||||
_tfopen(path.c_str(), _T("rb")), [](FILE* fp) { fclose(fp); });
|
||||
if (!fp) absl::FPrintF(stderr, "Failed to open executable\n");
|
||||
return fp;
|
||||
#else
|
||||
absl::FPrintF(stderr,
|
||||
"OpenTestExecutable() unimplemented on this platform\n");
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
::testing::Matcher<FILE*> FileHasSubstr(absl::string_view needle) {
|
||||
return MakeMatcher(new FileHasSubstrMatcher(needle));
|
||||
}
|
||||
};
|
||||
|
||||
// This tests whether out methodology for testing stripping works on this
|
||||
// platform by looking for one string that definitely ought to be there and one
|
||||
// that definitely ought not to. If this fails, none of the `StrippingTest`s
|
||||
// are going to produce meaningful results.
|
||||
TEST_F(StrippingTest, Control) {
|
||||
constexpr char kEncodedPositiveControl[] =
|
||||
"U3RyaXBwaW5nVGVzdC5Qb3NpdGl2ZUNvbnRyb2w=";
|
||||
const std::string encoded_negative_control =
|
||||
absl::Base64Escape("StrippingTest.NegativeControl");
|
||||
|
||||
// Verify this mainly so we can encode other strings and know definitely they
|
||||
// won't encode to `kEncodedPositiveControl`.
|
||||
EXPECT_THAT(Base64UnescapeOrDie("U3RyaXBwaW5nVGVzdC5Qb3NpdGl2ZUNvbnRyb2w="),
|
||||
Eq("StrippingTest.PositiveControl"));
|
||||
|
||||
auto exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(kEncodedPositiveControl));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(encoded_negative_control)));
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, Literal) {
|
||||
// We need to load a copy of the needle string into memory (so we can search
|
||||
// for it) without leaving it lying around in plaintext in the executable file
|
||||
// as would happen if we used a literal. We might (or might not) leave it
|
||||
// lying around later; that's what the tests are for!
|
||||
const std::string needle = absl::Base64Escape("StrippingTest.Literal");
|
||||
LOG(INFO) << "U3RyaXBwaW5nVGVzdC5MaXRlcmFs";
|
||||
auto exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
if (absl::LogSeverity::kInfo >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(needle)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, LiteralInExpression) {
|
||||
// We need to load a copy of the needle string into memory (so we can search
|
||||
// for it) without leaving it lying around in plaintext in the executable file
|
||||
// as would happen if we used a literal. We might (or might not) leave it
|
||||
// lying around later; that's what the tests are for!
|
||||
const std::string needle =
|
||||
absl::Base64Escape("StrippingTest.LiteralInExpression");
|
||||
LOG(INFO) << absl::StrCat("secret: ",
|
||||
"U3RyaXBwaW5nVGVzdC5MaXRlcmFsSW5FeHByZXNzaW9u");
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
if (absl::LogSeverity::kInfo >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(needle)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, Fatal) {
|
||||
// We need to load a copy of the needle string into memory (so we can search
|
||||
// for it) without leaving it lying around in plaintext in the executable file
|
||||
// as would happen if we used a literal. We might (or might not) leave it
|
||||
// lying around later; that's what the tests are for!
|
||||
const std::string needle = absl::Base64Escape("StrippingTest.Fatal");
|
||||
// We don't care if the LOG statement is actually executed, we're just
|
||||
// checking that it's stripped.
|
||||
if (kReallyDie) LOG(FATAL) << "U3RyaXBwaW5nVGVzdC5GYXRhbA==";
|
||||
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
if (absl::LogSeverity::kFatal >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(needle)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, DFatal) {
|
||||
// We need to load a copy of the needle string into memory (so we can search
|
||||
// for it) without leaving it lying around in plaintext in the executable file
|
||||
// as would happen if we used a literal. We might (or might not) leave it
|
||||
// lying around later; that's what the tests are for!
|
||||
const std::string needle = absl::Base64Escape("StrippingTest.DFatal");
|
||||
// We don't care if the LOG statement is actually executed, we're just
|
||||
// checking that it's stripped.
|
||||
if (kReallyDie) LOG(DFATAL) << "U3RyaXBwaW5nVGVzdC5ERmF0YWw=";
|
||||
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
// `DFATAL` can be `ERROR` or `FATAL`, and a compile-time optimizer doesn't
|
||||
// know which, because `absl::kLogDebugFatal` is declared `extern` and defined
|
||||
// in another TU. Link-time optimization might do better. We have six cases:
|
||||
// | `AMLL` is-> | `<=ERROR` | `FATAL` | `>FATAL` |
|
||||
// | ------------------- | --------- | ------- | -------- |
|
||||
// | `DFATAL` is `ERROR` | present | ? | stripped |
|
||||
// | `DFATAL` is `FATAL` | present | present | stripped |
|
||||
|
||||
// These constexpr variables are used to suppress unreachable code warnings
|
||||
// in the if-else statements below.
|
||||
|
||||
// "present" in the table above: `DFATAL` exceeds `ABSL_MIN_LOG_LEVEL`, so
|
||||
// `DFATAL` statements should not be stripped (and they should be logged
|
||||
// when executed, but that's a different testsuite).
|
||||
constexpr bool kExpectPresent = absl::kLogDebugFatal >= kAbslMinLogLevel;
|
||||
|
||||
// "stripped" in the table above: even though the compiler may not know
|
||||
// which value `DFATAL` has, it should be able to strip it since both
|
||||
// possible values ought to be stripped.
|
||||
constexpr bool kExpectStripped = kAbslMinLogLevel > absl::LogSeverity::kFatal;
|
||||
|
||||
if (kExpectPresent) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(needle));
|
||||
} else if (kExpectStripped) {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(needle)));
|
||||
} else {
|
||||
// "?" in the table above; may or may not be stripped depending on whether
|
||||
// any link-time optimization is done. Either outcome is ok.
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, Level) {
|
||||
const std::string needle = absl::Base64Escape("StrippingTest.Level");
|
||||
volatile auto severity = absl::LogSeverity::kWarning;
|
||||
// Ensure that `severity` is not a compile-time constant to prove that
|
||||
// stripping works regardless:
|
||||
LOG(LEVEL(severity)) << "U3RyaXBwaW5nVGVzdC5MZXZlbA==";
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
if (absl::LogSeverity::kFatal >= kAbslMinLogLevel) {
|
||||
// This can't be stripped at compile-time because it might evaluate to a
|
||||
// level that shouldn't be stripped.
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(needle));
|
||||
} else {
|
||||
#if (defined(_MSC_VER) && !defined(__clang__)) || defined(__APPLE__)
|
||||
// Dead code elimination misses this case.
|
||||
#else
|
||||
// All levels should be stripped, so it doesn't matter what the severity
|
||||
// winds up being.
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(needle)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, Check) {
|
||||
// Here we also need a variable name with enough entropy that it's unlikely to
|
||||
// appear in the binary by chance. `volatile` keeps the tautological
|
||||
// comparison (and the rest of the `CHECK`) from being optimized away.
|
||||
const std::string var_needle = absl::Base64Escape("StrippingTestCheckVar");
|
||||
const std::string msg_needle = absl::Base64Escape("StrippingTest.Check");
|
||||
volatile int U3RyaXBwaW5nVGVzdENoZWNrVmFy = 0xCAFE;
|
||||
// We don't care if the CHECK is actually executed, just that stripping works.
|
||||
// Hiding it behind `kReallyDie` works around some overly aggressive
|
||||
// optimizations in older versions of MSVC.
|
||||
if (kReallyDie) {
|
||||
CHECK(U3RyaXBwaW5nVGVzdENoZWNrVmFy != U3RyaXBwaW5nVGVzdENoZWNrVmFy)
|
||||
<< "U3RyaXBwaW5nVGVzdC5DaGVjaw==";
|
||||
}
|
||||
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
if (absl::LogSeverity::kFatal >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(var_needle));
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(msg_needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(var_needle)));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(msg_needle)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, CheckOp) {
|
||||
// See `StrippingTest.Check` for some hairy implementation notes.
|
||||
const std::string var_needle1 =
|
||||
absl::Base64Escape("StrippingTestCheckOpVar1");
|
||||
const std::string var_needle2 =
|
||||
absl::Base64Escape("StrippingTestCheckOpVar2");
|
||||
const std::string msg_needle = absl::Base64Escape("StrippingTest.CheckOp");
|
||||
volatile int U3RyaXBwaW5nVGVzdENoZWNrT3BWYXIx = 0xFEED;
|
||||
volatile int U3RyaXBwaW5nVGVzdENoZWNrT3BWYXIy = 0xCAFE;
|
||||
if (kReallyDie) {
|
||||
CHECK_EQ(U3RyaXBwaW5nVGVzdENoZWNrT3BWYXIx, U3RyaXBwaW5nVGVzdENoZWNrT3BWYXIy)
|
||||
<< "U3RyaXBwaW5nVGVzdC5DaGVja09w";
|
||||
}
|
||||
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
|
||||
if (absl::LogSeverity::kFatal >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(var_needle1));
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(var_needle2));
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(msg_needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(var_needle1)));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(var_needle2)));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(msg_needle)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, CheckStrOp) {
|
||||
// See `StrippingTest.Check` for some hairy implementation notes.
|
||||
const std::string var_needle1 =
|
||||
absl::Base64Escape("StrippingTestCheckStrOpVar1");
|
||||
const std::string var_needle2 =
|
||||
absl::Base64Escape("StrippingTestCheckStrOpVar2");
|
||||
const std::string msg_needle = absl::Base64Escape("StrippingTest.CheckStrOp");
|
||||
const char *volatile U3RyaXBwaW5nVGVzdENoZWNrU3RyT3BWYXIx = "FEED";
|
||||
const char *volatile U3RyaXBwaW5nVGVzdENoZWNrU3RyT3BWYXIy = "CAFE";
|
||||
if (kReallyDie) {
|
||||
CHECK_STREQ(U3RyaXBwaW5nVGVzdENoZWNrU3RyT3BWYXIx,
|
||||
U3RyaXBwaW5nVGVzdENoZWNrU3RyT3BWYXIy)
|
||||
<< "U3RyaXBwaW5nVGVzdC5DaGVja1N0ck9w";
|
||||
}
|
||||
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
|
||||
if (absl::LogSeverity::kFatal >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(var_needle1));
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(var_needle2));
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(msg_needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(var_needle1)));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(var_needle2)));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(msg_needle)));
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(StrippingTest, CheckOk) {
|
||||
// See `StrippingTest.Check` for some hairy implementation notes.
|
||||
const std::string var_needle = absl::Base64Escape("StrippingTestCheckOkVar1");
|
||||
const std::string msg_needle = absl::Base64Escape("StrippingTest.CheckOk");
|
||||
volatile bool x = false;
|
||||
auto U3RyaXBwaW5nVGVzdENoZWNrT2tWYXIx = absl::OkStatus();
|
||||
if (x) {
|
||||
U3RyaXBwaW5nVGVzdENoZWNrT2tWYXIx =
|
||||
absl::InvalidArgumentError("Stripping this is not my job!");
|
||||
}
|
||||
if (kReallyDie) {
|
||||
CHECK_OK(U3RyaXBwaW5nVGVzdENoZWNrT2tWYXIx)
|
||||
<< "U3RyaXBwaW5nVGVzdC5DaGVja09r";
|
||||
}
|
||||
|
||||
std::unique_ptr<FILE, std::function<void(FILE*)>> exe = OpenTestExecutable();
|
||||
ASSERT_THAT(exe, NotNull());
|
||||
|
||||
if (absl::LogSeverity::kFatal >= kAbslMinLogLevel) {
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(var_needle));
|
||||
EXPECT_THAT(exe.get(), FileHasSubstr(msg_needle));
|
||||
} else {
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(var_needle)));
|
||||
EXPECT_THAT(exe.get(), Not(FileHasSubstr(msg_needle)));
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
75
TMessagesProj/jni/voip/webrtc/absl/log/structured.h
Normal file
75
TMessagesProj/jni/voip/webrtc/absl/log/structured.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/structured.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header declares APIs supporting structured logging, allowing log
|
||||
// statements to be more easily parsed, especially by automated processes.
|
||||
//
|
||||
// When structured logging is in use, data streamed into a `LOG` statement are
|
||||
// encoded as `Value` fields in a `logging.proto.Event` protocol buffer message.
|
||||
// The individual data are exposed programmatically to `LogSink`s and to the
|
||||
// user via some log reading tools which are able to query the structured data
|
||||
// more usefully than would be possible if each message was a single opaque
|
||||
// string. These helpers allow user code to add additional structure to the
|
||||
// data they stream.
|
||||
|
||||
#ifndef ABSL_LOG_STRUCTURED_H_
|
||||
#define ABSL_LOG_STRUCTURED_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/base/config.h"
|
||||
#include "absl/log/internal/structured.h"
|
||||
#include "absl/strings/string_view.h"
|
||||
|
||||
namespace absl {
|
||||
ABSL_NAMESPACE_BEGIN
|
||||
|
||||
// LogAsLiteral()
|
||||
//
|
||||
// Annotates its argument as a string literal so that structured logging
|
||||
// captures it as a `literal` field instead of a `str` field (the default).
|
||||
// This does not affect the text representation, only the structure.
|
||||
//
|
||||
// Streaming `LogAsLiteral(s)` into a `std::ostream` behaves just like streaming
|
||||
// `s` directly.
|
||||
//
|
||||
// Using `LogAsLiteral()` is occasionally appropriate and useful when proxying
|
||||
// data logged from another system or another language. For example:
|
||||
//
|
||||
// void Logger::LogString(absl::string_view str, absl::LogSeverity severity,
|
||||
// const char *file, int line) {
|
||||
// LOG(LEVEL(severity)).AtLocation(file, line) << str;
|
||||
// }
|
||||
// void Logger::LogStringLiteral(absl::string_view str,
|
||||
// absl::LogSeverity severity, const char *file,
|
||||
// int line) {
|
||||
// LOG(LEVEL(severity)).AtLocation(file, line) << absl::LogAsLiteral(str);
|
||||
// }
|
||||
//
|
||||
// `LogAsLiteral` should only be used as a streaming operand and not, for
|
||||
// example, as a local variable initializer.
|
||||
inline log_internal::AsLiteralImpl LogAsLiteral(
|
||||
absl::string_view s ABSL_ATTRIBUTE_LIFETIME_BOUND) {
|
||||
return log_internal::AsLiteralImpl(s);
|
||||
}
|
||||
|
||||
ABSL_NAMESPACE_END
|
||||
} // namespace absl
|
||||
|
||||
#endif // ABSL_LOG_STRUCTURED_H_
|
||||
63
TMessagesProj/jni/voip/webrtc/absl/log/structured_test.cc
Normal file
63
TMessagesProj/jni/voip/webrtc/absl/log/structured_test.cc
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
//
|
||||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/structured.h"
|
||||
|
||||
#include <ios>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/attributes.h"
|
||||
#include "absl/log/internal/test_helpers.h"
|
||||
#include "absl/log/internal/test_matchers.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
|
||||
namespace {
|
||||
using ::absl::log_internal::MatchesOstream;
|
||||
using ::absl::log_internal::TextMessage;
|
||||
using ::testing::ElementsAre;
|
||||
using ::testing::Eq;
|
||||
|
||||
auto *test_env ABSL_ATTRIBUTE_UNUSED = ::testing::AddGlobalTestEnvironment(
|
||||
new absl::log_internal::LogTestEnvironment);
|
||||
|
||||
// Abseil Logging library uses these by default, so we set them on the
|
||||
// `std::ostream` we compare against too.
|
||||
std::ios &LoggingDefaults(std::ios &str) {
|
||||
str.setf(std::ios_base::showbase | std::ios_base::boolalpha |
|
||||
std::ios_base::internal);
|
||||
return str;
|
||||
}
|
||||
|
||||
TEST(StreamingFormatTest, LogAsLiteral) {
|
||||
std::ostringstream stream;
|
||||
const std::string not_a_literal("hello world");
|
||||
stream << LoggingDefaults << absl::LogAsLiteral(not_a_literal);
|
||||
|
||||
absl::ScopedMockLog sink;
|
||||
|
||||
EXPECT_CALL(sink, Send(AllOf(TextMessage(MatchesOstream(stream)),
|
||||
TextMessage(Eq("hello world")),
|
||||
ENCODED_MESSAGE(HasValues(ElementsAre(
|
||||
ValueWithLiteral(Eq("hello world"))))))));
|
||||
|
||||
sink.StartCapturingLogs();
|
||||
LOG(INFO) << absl::LogAsLiteral(not_a_literal);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
74
TMessagesProj/jni/voip/webrtc/absl/log/vlog_is_on.h
Normal file
74
TMessagesProj/jni/voip/webrtc/absl/log/vlog_is_on.h
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
// Copyright 2022 The Abseil Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
//
|
||||
// -----------------------------------------------------------------------------
|
||||
// File: log/vlog_is_on.h
|
||||
// -----------------------------------------------------------------------------
|
||||
//
|
||||
// This header defines the `VLOG_IS_ON()` macro that controls the
|
||||
// variable-verbosity conditional logging.
|
||||
//
|
||||
// It's used by `VLOG` in log.h, or it can also be used directly like this:
|
||||
//
|
||||
// if (VLOG_IS_ON(2)) {
|
||||
// foo_server.RecomputeStatisticsExpensive();
|
||||
// LOG(INFO) << foo_server.LastStatisticsAsString();
|
||||
// }
|
||||
//
|
||||
// Each source file has an effective verbosity level that's a non-negative
|
||||
// integer computed from the `--vmodule` and `--v` flags.
|
||||
// `VLOG_IS_ON(n)` is true, and `VLOG(n)` logs, if that effective verbosity
|
||||
// level is greater than or equal to `n`.
|
||||
//
|
||||
// `--vmodule` takes a comma-delimited list of key=value pairs. Each key is a
|
||||
// pattern matched against filenames, and the values give the effective severity
|
||||
// level applied to matching files. '?' and '*' characters in patterns are
|
||||
// interpreted as single-character and zero-or-more-character wildcards.
|
||||
// Patterns including a slash character are matched against full pathnames,
|
||||
// while those without are matched against basenames only. One suffix (i.e. the
|
||||
// last . and everything after it) is stripped from each filename prior to
|
||||
// matching, as is the special suffix "-inl".
|
||||
//
|
||||
// Example: --vmodule=module_a=1,module_b=2
|
||||
//
|
||||
// Files are matched against globs in `--vmodule` in order, and the first match
|
||||
// determines the verbosity level.
|
||||
//
|
||||
// Files which do not match any pattern in `--vmodule` use the value of `--v` as
|
||||
// their effective verbosity level. The default is 0.
|
||||
//
|
||||
// SetVLogLevel helper function is provided to do limited dynamic control over
|
||||
// V-logging by appending to `--vmodule`. Because these go at the beginning of
|
||||
// the list, they take priority over any globs previously added.
|
||||
//
|
||||
// Resetting --vmodule will override all previous modifications to `--vmodule`,
|
||||
// including via SetVLogLevel.
|
||||
|
||||
#ifndef ABSL_LOG_VLOG_IS_ON_H_
|
||||
#define ABSL_LOG_VLOG_IS_ON_H_
|
||||
|
||||
#include "absl/log/absl_vlog_is_on.h" // IWYU pragma: export
|
||||
|
||||
// IWYU pragma: private, include "absl/log/log.h"
|
||||
|
||||
// Each VLOG_IS_ON call site gets its own VLogSite that registers with the
|
||||
// global linked list of sites to asynchronously update its verbosity level on
|
||||
// changes to --v or --vmodule. The verbosity can also be set by manually
|
||||
// calling SetVLogLevel.
|
||||
//
|
||||
// VLOG_IS_ON is not async signal safe, but it is guaranteed not to allocate
|
||||
// new memory.
|
||||
#define VLOG_IS_ON(verbose_level) ABSL_VLOG_IS_ON(verbose_level)
|
||||
|
||||
#endif // ABSL_LOG_VLOG_IS_ON_H_
|
||||
233
TMessagesProj/jni/voip/webrtc/absl/log/vlog_is_on_test.cc
Normal file
233
TMessagesProj/jni/voip/webrtc/absl/log/vlog_is_on_test.cc
Normal file
|
|
@ -0,0 +1,233 @@
|
|||
// Copyright 2023 The Abseil Authors
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
#include "absl/log/vlog_is_on.h"
|
||||
|
||||
#include "gmock/gmock.h"
|
||||
#include "gtest/gtest.h"
|
||||
#include "absl/base/log_severity.h"
|
||||
#include "absl/flags/flag.h"
|
||||
#include "absl/log/flags.h"
|
||||
#include "absl/log/globals.h"
|
||||
#include "absl/log/log.h"
|
||||
#include "absl/log/scoped_mock_log.h"
|
||||
#include "absl/types/optional.h"
|
||||
|
||||
namespace {
|
||||
|
||||
using ::testing::_;
|
||||
|
||||
absl::optional<int> MaxLogVerbosity() {
|
||||
#ifdef ABSL_MAX_VLOG_VERBOSITY
|
||||
return ABSL_MAX_VLOG_VERBOSITY;
|
||||
#else
|
||||
return absl::nullopt;
|
||||
#endif
|
||||
}
|
||||
|
||||
absl::optional<int> MinLogLevel() {
|
||||
#ifdef ABSL_MIN_LOG_LEVEL
|
||||
return static_cast<int>(ABSL_MIN_LOG_LEVEL);
|
||||
#else
|
||||
return absl::nullopt;
|
||||
#endif
|
||||
}
|
||||
|
||||
// This fixture is used to reset the VLOG levels to their default values before
|
||||
// each test.
|
||||
class VLogIsOnTest : public ::testing::Test {
|
||||
protected:
|
||||
void SetUp() override { ResetVLogLevels(); }
|
||||
|
||||
private:
|
||||
// Resets the VLOG levels to their default values.
|
||||
// It is supposed to be called in the SetUp() method of the test fixture to
|
||||
// eliminate any side effects from other tests.
|
||||
static void ResetVLogLevels() {
|
||||
absl::log_internal::UpdateVModule("");
|
||||
absl::SetGlobalVLogLevel(0);
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(VLogIsOnTest, GlobalWorksWithoutMaxVerbosityAndMinLogLevel) {
|
||||
if (MaxLogVerbosity().has_value() || MinLogLevel().has_value()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
absl::SetGlobalVLogLevel(3);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "important"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(3) << "important";
|
||||
VLOG(4) << "spam";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, FileWorksWithoutMaxVerbosityAndMinLogLevel) {
|
||||
if (MaxLogVerbosity().has_value() || MinLogLevel().has_value()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
absl::SetVLogLevel("vlog_is_on_test", 3);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "important"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(3) << "important";
|
||||
VLOG(4) << "spam";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, PatternWorksWithoutMaxVerbosityAndMinLogLevel) {
|
||||
if (MaxLogVerbosity().has_value() || MinLogLevel().has_value()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
absl::SetVLogLevel("vlog_is_on*", 3);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "important"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(3) << "important";
|
||||
VLOG(4) << "spam";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest,
|
||||
PatternOverridesLessGenericOneWithoutMaxVerbosityAndMinLogLevel) {
|
||||
if (MaxLogVerbosity().has_value() || MinLogLevel().has_value()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// This should disable logging in this file
|
||||
absl::SetVLogLevel("vlog_is_on*", -1);
|
||||
// This overrides the previous setting, because "vlog*" is more generic than
|
||||
// "vlog_is_on*". This should enable VLOG level 3 in this file.
|
||||
absl::SetVLogLevel("vlog*", 3);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "important"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(3) << "important";
|
||||
VLOG(4) << "spam";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest,
|
||||
PatternDoesNotOverridesMoreGenericOneWithoutMaxVerbosityAndMinLogLevel) {
|
||||
if (MaxLogVerbosity().has_value() || MinLogLevel().has_value()) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// This should enable VLOG level 3 in this file.
|
||||
absl::SetVLogLevel("vlog*", 3);
|
||||
// This should not change the VLOG level in this file. The pattern does not
|
||||
// match this file and it is less generic than the previous patter "vlog*".
|
||||
// Therefore, it does not disable VLOG level 3 in this file.
|
||||
absl::SetVLogLevel("vlog_is_on_some_other_test*", -1);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "important"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(3) << "important";
|
||||
VLOG(5) << "spam";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, GlobalDoesNotFilterBelowMaxVerbosity) {
|
||||
if (!MaxLogVerbosity().has_value() || *MaxLogVerbosity() < 2) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// Set an arbitrary high value to avoid filtering VLOGs in tests by default.
|
||||
absl::SetGlobalVLogLevel(1000);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "asdf"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(2) << "asdf";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, FileDoesNotFilterBelowMaxVerbosity) {
|
||||
if (!MaxLogVerbosity().has_value() || *MaxLogVerbosity() < 2) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// Set an arbitrary high value to avoid filtering VLOGs in tests by default.
|
||||
absl::SetVLogLevel("vlog_is_on_test", 1000);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "asdf"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(2) << "asdf";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, PatternDoesNotFilterBelowMaxVerbosity) {
|
||||
if (!MaxLogVerbosity().has_value() || *MaxLogVerbosity() < 2) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// Set an arbitrary high value to avoid filtering VLOGs in tests by default.
|
||||
absl::SetVLogLevel("vlog_is_on*", 1000);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
EXPECT_CALL(log, Log(absl::LogSeverity::kInfo, _, "asdf"));
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(2) << "asdf";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, GlobalFiltersAboveMaxVerbosity) {
|
||||
if (!MaxLogVerbosity().has_value() || *MaxLogVerbosity() >= 4) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// Set an arbitrary high value to avoid filtering VLOGs in tests by default.
|
||||
absl::SetGlobalVLogLevel(1000);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(4) << "dfgh";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, FileFiltersAboveMaxVerbosity) {
|
||||
if (!MaxLogVerbosity().has_value() || *MaxLogVerbosity() >= 4) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// Set an arbitrary high value to avoid filtering VLOGs in tests by default.
|
||||
absl::SetVLogLevel("vlog_is_on_test", 1000);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(4) << "dfgh";
|
||||
}
|
||||
|
||||
TEST_F(VLogIsOnTest, PatternFiltersAboveMaxVerbosity) {
|
||||
if (!MaxLogVerbosity().has_value() || *MaxLogVerbosity() >= 4) {
|
||||
GTEST_SKIP();
|
||||
}
|
||||
|
||||
// Set an arbitrary high value to avoid filtering VLOGs in tests by default.
|
||||
absl::SetVLogLevel("vlog_is_on*", 1000);
|
||||
absl::ScopedMockLog log(absl::MockLogDefault::kDisallowUnexpected);
|
||||
|
||||
log.StartCapturingLogs();
|
||||
VLOG(4) << "dfgh";
|
||||
}
|
||||
|
||||
} // namespace
|
||||
Loading…
Add table
Add a link
Reference in a new issue