修改pods

This commit is contained in:
2025-09-20 17:13:38 +08:00
parent 7787b3ee30
commit 28ff2b0264
5251 changed files with 345029 additions and 285168 deletions

117
Pods/abseil/absl/log/absl_check.h generated Normal file
View 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_

115
Pods/abseil/absl/log/absl_log.h generated Normal file
View 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_

93
Pods/abseil/absl/log/absl_vlog_is_on.h generated Normal file
View File

@@ -0,0 +1,93 @@
// 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".
//
// 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
Pods/abseil/absl/log/check.h generated Normal file
View 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_

178
Pods/abseil/absl/log/globals.cc generated Normal file
View 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
Pods/abseil/absl/log/globals.h generated Normal file
View 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_

View File

@@ -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
Pods/abseil/absl/log/internal/check_impl.h generated Normal file
View 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_

138
Pods/abseil/absl/log/internal/check_op.cc generated Normal file
View File

@@ -0,0 +1,138 @@
// 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 <string.h>
#include <ostream>
#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
#include <sstream>
#include <string>
#include "absl/base/config.h"
#include "absl/strings/str_cat.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
#define ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(x) \
template std::string* MakeCheckOpString(x, x, const char*)
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(bool);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(int64_t);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(uint64_t);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(float);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(double);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(char);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(unsigned char);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const std::string&);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const absl::string_view&);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const char*);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const signed char*);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const unsigned char*);
ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING(const void*);
#undef ABSL_LOGGING_INTERNAL_DEFINE_MAKE_CHECK_OP_STRING
CheckOpMessageBuilder::CheckOpMessageBuilder(const char* exprtext) {
stream_ << exprtext << " (";
}
std::ostream& CheckOpMessageBuilder::ForVar2() {
stream_ << " vs. ";
return stream_;
}
std::string* CheckOpMessageBuilder::NewString() {
stream_ << ")";
return new std::string(stream_.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) \
std::string* Check##func##expected##Impl(const char* s1, const char* s2, \
const char* exprtext) { \
bool equal = s1 == s2 || (s1 && s2 && !func(s1, s2)); \
if (equal == expected) { \
return nullptr; \
} else { \
return new std::string( \
absl::StrCat(exprtext, " (", s1, " vs. ", s2, ")")); \
} \
}
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

462
Pods/abseil/absl/log/internal/check_op.h generated Normal file
View File

@@ -0,0 +1,462 @@
// 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/config.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 (::std::string* absl_log_internal_check_op_result \
ABSL_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_STRIP_LOG = \
::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_log_internal_check_op_result).InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_OP(name, op, val1, val1_text, val2, \
val2_text) \
while (::std::string* 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_log_internal_qcheck_op_result).InternalStream()
#define ABSL_LOG_INTERNAL_CHECK_STROP(func, op, expected, s1, s1_text, s2, \
s2_text) \
while (::std::string* 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_log_internal_check_strop_result) \
.InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_STROP(func, op, expected, s1, s1_text, s2, \
s2_text) \
while (::std::string* 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_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<const ::absl::Status*, ::std::string*> \
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_log_internal_check_ok_goo.second) \
.InternalStream()
#define ABSL_LOG_INTERNAL_QCHECK_OK(val, val_text) \
for (::std::pair<const ::absl::Status*, ::std::string*> \
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_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 std::string* MakeCheckFailString(
const absl::Status* status, 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 const absl::Status* AsStatus(const absl::Status& s) { return &s; }
template <typename T>
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(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 `)`).
std::string* 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 std::string* MakeCheckOpString(
T1 v1, T2 v2, const char* exprtext) ABSL_ATTRIBUTE_NOINLINE;
template <typename T1, typename T2>
std::string* MakeCheckOpString(T1 v1, T2 v2, 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 std::string* MakeCheckOpString(x, x, 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) \
: new std::string())
#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 ::std::string* name##Impl(const T1& v1, const T2& v2, \
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 ::std::string* name##Impl(int v1, int v2, \
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
std::string* CheckstrcmptrueImpl(const char* s1, const char* s2,
const char* exprtext);
std::string* CheckstrcmpfalseImpl(const char* s1, const char* s2,
const char* exprtext);
std::string* CheckstrcasecmptrueImpl(const char* s1, const char* s2,
const char* exprtext);
std::string* CheckstrcasecmpfalseImpl(const char* s1, const char* s2,
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.
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; } // NOLINT
inline constexpr unsigned short GetReferenceableValue( // NOLINT
unsigned short t) { // NOLINT
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; } // NOLINT
inline constexpr unsigned long GetReferenceableValue( // NOLINT
unsigned long t) { // NOLINT
return t;
}
inline constexpr long long GetReferenceableValue(long long t) { // NOLINT
return t;
}
inline constexpr unsigned long long GetReferenceableValue( // NOLINT
unsigned long long t) { // NOLINT
return t;
}
} // namespace log_internal
ABSL_NAMESPACE_END
} // namespace absl
#endif // ABSL_LOG_INTERNAL_CHECK_OP_H_

View File

@@ -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
Pods/abseil/absl/log/internal/conditions.h generated Normal file
View 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
Pods/abseil/absl/log/internal/config.h generated Normal file
View 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_

73
Pods/abseil/absl/log/internal/fnmatch.cc generated Normal file
View 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
Pods/abseil/absl/log/internal/fnmatch.h generated Normal file
View 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_

145
Pods/abseil/absl/log/internal/globals.cc generated Normal file
View 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
Pods/abseil/absl/log/internal/globals.h generated Normal file
View 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_

View 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

View 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
Pods/abseil/absl/log/internal/log_impl.h generated Normal file
View 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_

View File

@@ -0,0 +1,690 @@
//
// 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/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/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(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::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(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(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(const char* file, int line, InfoTag)
: LogMessage(file, line, absl::LogSeverity::kInfo) {}
LogMessage::LogMessage(const char* file, int line, WarningTag)
: LogMessage(file, line, absl::LogSeverity::kWarning) {}
LogMessage::LogMessage(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::LogSink* sink) {
ABSL_INTERNAL_CHECK(sink, "null LogSink*");
data_->extra_sinks.push_back(sink);
return *this;
}
LogMessage& LogMessage::ToSinkOnly(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;
}
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); // NOLINT
template LogMessage& LogMessage::operator<<(const unsigned short& v); // NOLINT
template LogMessage& LogMessage::operator<<(const int& v);
template LogMessage& LogMessage::operator<<(const unsigned int& v);
template LogMessage& LogMessage::operator<<(const long& v); // NOLINT
template LogMessage& LogMessage::operator<<(const unsigned long& v); // NOLINT
template LogMessage& LogMessage::operator<<(const long long& v); // NOLINT
template LogMessage& LogMessage::operator<<(
const unsigned long long& v); // NOLINT
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);
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();
auto start = EncodeMessageStart(
EventTag::kValue, BufferSizeFor(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(str_type == StringType::kLiteral
? ValueTag::kStringLiteral
: ValueTag::kString,
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();
auto value_start = EncodeMessageStart(
EventTag::kValue, BufferSizeFor(WireType::kLengthDelimited) + num,
&encoded_remaining_copy);
auto str_start = EncodeMessageStart(str_type == StringType::kLiteral
? ValueTag::kStringLiteral
: ValueTag::kString,
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);
// 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(const char* file, int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {}
LogMessageFatal::LogMessageFatal(const char* file, int line,
absl::string_view failure_msg)
: LogMessage(file, line, absl::LogSeverity::kFatal) {
*this << "Check failed: " << failure_msg << " ";
}
LogMessageFatal::~LogMessageFatal() {
Flush();
FailWithoutStackTrace();
}
LogMessageDebugFatal::LogMessageDebugFatal(const char* file, int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {}
LogMessageDebugFatal::~LogMessageDebugFatal() {
Flush();
FailWithoutStackTrace();
}
LogMessageQuietlyDebugFatal::LogMessageQuietlyDebugFatal(const char* file,
int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {
SetFailQuietly();
}
LogMessageQuietlyDebugFatal::~LogMessageQuietlyDebugFatal() {
Flush();
FailQuietly();
}
LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line)
: LogMessage(file, line, absl::LogSeverity::kFatal) {
SetFailQuietly();
}
LogMessageQuietlyFatal::LogMessageQuietlyFatal(const char* file, int line,
absl::string_view 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

View File

@@ -0,0 +1,394 @@
// 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 <ios>
#include <memory>
#include <ostream>
#include <streambuf>
#include <string>
#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/log/internal/nullguard.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;
class LogMessage {
public:
struct InfoTag {};
struct WarningTag {};
struct ErrorTag {};
// Used for `LOG`.
LogMessage(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(const char* file, int line,
InfoTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
LogMessage(const char* file, int line,
WarningTag) ABSL_ATTRIBUTE_COLD ABSL_ATTRIBUTE_NOINLINE;
LogMessage(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. `sink` must not be null.
LogMessage& ToSinkAlso(absl::LogSink* sink);
// Sends this message to `*sink` and no others. `sink` must not be null.
LogMessage& ToSinkOnly(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).
// 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) { // NOLINT
return operator<< <signed short>(v); // NOLINT
}
LogMessage& operator<<(signed int v) { return operator<< <signed int>(v); }
LogMessage& operator<<(signed long v) { // NOLINT
return operator<< <signed long>(v); // NOLINT
}
LogMessage& operator<<(signed long long v) { // NOLINT
return operator<< <signed long long>(v); // NOLINT
}
LogMessage& operator<<(unsigned short v) { // NOLINT
return operator<< <unsigned short>(v); // NOLINT
}
LogMessage& operator<<(unsigned int v) {
return operator<< <unsigned int>(v);
}
LogMessage& operator<<(unsigned long v) { // NOLINT
return operator<< <unsigned long>(v); // NOLINT
}
LogMessage& operator<<(unsigned long long v) { // NOLINT
return operator<< <unsigned long long>(v); // NOLINT
}
LogMessage& operator<<(void* v) { return operator<< <void*>(v); }
LogMessage& operator<<(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
// 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<<(std::ostream& (*m)(std::ostream& os));
LogMessage& operator<<(std::ios_base& (*m)(std::ios_base& os));
// 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;
// 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;
// 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.
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(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.
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); // NOLINT
extern template LogMessage& LogMessage::operator<<(
const unsigned short& v); // NOLINT
extern template LogMessage& LogMessage::operator<<(const int& v);
extern template LogMessage& LogMessage::operator<<(
const unsigned int& v); // NOLINT
extern template LogMessage& LogMessage::operator<<(const long& v); // NOLINT
extern template LogMessage& LogMessage::operator<<(
const unsigned long& v); // NOLINT
extern template LogMessage& LogMessage::operator<<(
const long long& v); // NOLINT
extern template LogMessage& LogMessage::operator<<(
const unsigned long long& v); // NOLINT
extern template LogMessage& LogMessage::operator<<(void* const& v);
extern template LogMessage& LogMessage::operator<<(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);
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(const char* file, int line) ABSL_ATTRIBUTE_COLD;
LogMessageFatal(const char* file, int line,
absl::string_view 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(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(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(const char* file, int line) ABSL_ATTRIBUTE_COLD;
LogMessageQuietlyFatal(const char* file, int line,
absl::string_view 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_

View 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

View File

@@ -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_

View 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

View 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
Pods/abseil/absl/log/internal/nullstream.h generated Normal file
View 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_

220
Pods/abseil/absl/log/internal/proto.cc generated Normal file
View File

@@ -0,0 +1,220 @@
// 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);
}
constexpr uint64_t MakeTagType(uint64_t tag, WireType type) {
return tag << 3 | static_cast<uint64_t>(type);
}
} // 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

288
Pods/abseil/absl/log/internal/proto.h generated Normal file
View File

@@ -0,0 +1,288 @@
// 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;
}
// `BufferSizeFor` returns a number of bytes guaranteed to be sufficient to
// store encoded fields of the specified WireTypes regardless of tag numbers and
// 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() { return 0; }
template <typename... T>
constexpr size_t BufferSizeFor(WireType type, T... tail) {
// tag_type + data + ...
return MaxVarintSize() +
(type == WireType::kVarint ? MaxVarintSize() : //
type == WireType::k64Bit ? 8 : //
type == WireType::k32Bit ? 4 : MaxVarintSize()) + //
BufferSizeFor(tail...);
}
// 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_

108
Pods/abseil/absl/log/internal/strip.h generated Normal file
View File

@@ -0,0 +1,108 @@
// 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
// Attribute for marking variables used in implementation details of logging
// macros as unused, but only when `STRIP_LOG` is defined.
// With `STRIP_LOG` on, not marking them triggers `-Wunused-but-set-variable`,
// With `STRIP_LOG` off, marking them triggers `-Wused-but-marked-unused`.
//
// TODO(b/290784225): Replace this macro with attribute [[maybe_unused]] when
// Abseil stops supporting C++14.
#define ABSL_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_STRIP_LOG ABSL_ATTRIBUTE_UNUSED
#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_LOG_INTERNAL_ATTRIBUTE_UNUSED_IF_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_

View File

@@ -0,0 +1,340 @@
// 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) {
return FNMatch(info.module_pattern, 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

View 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_

44
Pods/abseil/absl/log/internal/voidify.h generated Normal file
View 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_

365
Pods/abseil/absl/log/log.h generated Normal file
View File

@@ -0,0 +1,365 @@
// 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
//
// An instance of `LOG_EVERY_N` increments a hidden zero-initialized counter
// every time execution passes through it and logs the specified message when
// the counter's value is a multiple of `n`, doing nothing otherwise. Each
// instance has its own counter. The counter's value can be logged by streaming
// the symbol `COUNTER`. `LOG_EVERY_N` is thread-safe.
// Example:
//
// LOG_EVERY_N(WARNING, 1000) << "Got a packet with a bad CRC (" << COUNTER
// << " total)";
#define LOG_EVERY_N(severity, n) \
ABSL_LOG_INTERNAL_LOG_EVERY_N_IMPL(_##severity, n)
// LOG_FIRST_N
//
// `LOG_FIRST_N` behaves like `LOG_EVERY_N` except that the specified message is
// logged when the counter's value is less than `n`. `LOG_FIRST_N` is
// thread-safe.
#define LOG_FIRST_N(severity, n) \
ABSL_LOG_INTERNAL_LOG_FIRST_N_IMPL(_##severity, n)
// LOG_EVERY_POW_2
//
// `LOG_EVERY_POW_2` behaves like `LOG_EVERY_N` except that the specified
// message is logged when the counter's value is a power of 2.
// `LOG_EVERY_POW_2` is thread-safe.
#define LOG_EVERY_POW_2(severity) \
ABSL_LOG_INTERNAL_LOG_EVERY_POW_2_IMPL(_##severity)
// LOG_EVERY_N_SEC
//
// An instance of `LOG_EVERY_N_SEC` uses a hidden state variable to log the
// specified message at most once every `n_seconds`. A hidden counter of
// executions (whether a message is logged or not) is also maintained and can be
// logged by streaming the symbol `COUNTER`. `LOG_EVERY_N_SEC` is thread-safe.
// Example:
//
// LOG_EVERY_N_SEC(INFO, 2.5) << "Got " << COUNTER << " cookies so far";
#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)
// `LOG_IF_EVERY_N` and friends behave as the corresponding `LOG_EVERY_N`
// but neither increment a counter nor log a message if condition is false (as
// `LOG_IF`).
// Example:
//
// LOG_IF_EVERY_N(INFO, (size > 1024), 10) << "Got the " << COUNTER
// << "th big cookie";
#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_

41
Pods/abseil/absl/log/log_entry.cc generated Normal file
View 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
Pods/abseil/absl/log/log_entry.h generated Normal file
View 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_

23
Pods/abseil/absl/log/log_sink.cc generated Normal file
View 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
Pods/abseil/absl/log/log_sink.h generated Normal file
View 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_

61
Pods/abseil/absl/log/log_sink_registry.h generated Normal file
View File

@@ -0,0 +1,61 @@
// 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/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::LogSink* sink) { log_internal::AddLogSink(sink); }
inline void RemoveLogSink(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_

72
Pods/abseil/absl/log/vlog_is_on.h generated Normal file
View File

@@ -0,0 +1,72 @@
// 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".
//
// 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_