Commit fb977908 authored by Gyuyoung Kim's avatar Gyuyoung Kim Committed by Commit Bot

Separate ScopedLogger class from wtf/Assertion.cpp/h

As a step to reduce uses of wtf/Assertions.cpp/h, this CL extracts ScopedLogger class
from Assertions.cpp/h files.

BUG=596760

TEST: The unit test for ScopedLogger starts to work on ScopedLoggerTest.cpp.
Change-Id: Iceaee21136fae9244c96579f3a7bd963f89b2eec
Reviewed-on: https://chromium-review.googlesource.com/577576
Commit-Queue: Gyuyoung Kim <gyuyoung.kim@chromium.org>
Reviewed-by: default avatarKent Tamura <tkent@chromium.org>
Cr-Commit-Position: refs/heads/master@{#490753}
parent 7cfb8d0d
......@@ -34,15 +34,8 @@
#include "platform/wtf/Assertions.h"
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>
#include "build/build_config.h"
#include "platform/wtf/PtrUtil.h"
#include "platform/wtf/ThreadSpecific.h"
#include "platform/wtf/Threading.h"
#if defined(OS_MACOSX)
#include <asl.h>
......@@ -67,7 +60,7 @@
#endif
PRINTF_FORMAT(1, 0)
static void vprintf_stderr_common(const char* format, va_list args) {
void vprintf_stderr_common(const char* format, va_list args) {
#if defined(OS_MACOSX)
va_list copyOfArgs;
va_copy(copyOfArgs, args);
......@@ -124,96 +117,6 @@ static void vprintf_stderr_with_trailing_newline(const char* format,
#pragma GCC diagnostic pop
#endif
#if DCHECK_IS_ON()
namespace WTF {
ScopedLogger::ScopedLogger(bool condition, const char* format, ...)
: parent_(condition ? Current() : 0), multiline_(false) {
if (!condition)
return;
va_list args;
va_start(args, format);
Init(format, args);
va_end(args);
}
ScopedLogger::~ScopedLogger() {
if (Current() == this) {
if (multiline_)
Indent();
else
Print(" ");
Print(")\n");
Current() = parent_;
}
}
void ScopedLogger::SetPrintFuncForTests(PrintFunctionPtr ptr) {
print_func_ = ptr;
};
void ScopedLogger::Init(const char* format, va_list args) {
Current() = this;
if (parent_)
parent_->WriteNewlineIfNeeded();
Indent();
Print("( ");
print_func_(format, args);
}
void ScopedLogger::WriteNewlineIfNeeded() {
if (!multiline_) {
Print("\n");
multiline_ = true;
}
}
void ScopedLogger::Indent() {
if (parent_) {
parent_->Indent();
PrintIndent();
}
}
void ScopedLogger::Log(const char* format, ...) {
if (Current() != this)
return;
va_list args;
va_start(args, format);
WriteNewlineIfNeeded();
Indent();
PrintIndent();
print_func_(format, args);
Print("\n");
va_end(args);
}
void ScopedLogger::Print(const char* format, ...) {
va_list args;
va_start(args, format);
print_func_(format, args);
va_end(args);
}
void ScopedLogger::PrintIndent() {
Print(" ");
}
ScopedLogger*& ScopedLogger::Current() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<ScopedLogger*>, ref, ());
return *ref;
}
ScopedLogger::PrintFunctionPtr ScopedLogger::print_func_ =
vprintf_stderr_common;
} // namespace WTF
#endif // DCHECK_IS_ON
void WTFLogAlways(const char* format, ...) {
va_list args;
va_start(args, format);
......
......@@ -30,73 +30,17 @@
#include <stdarg.h>
#include "base/compiler_specific.h"
#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "platform/wtf/Noncopyable.h"
#include "platform/wtf/WTFExport.h"
// New code shouldn't use this function. This function will be deprecated.
void vprintf_stderr_common(const char* format, va_list args);
// WTFLogAlways() is deprecated. crbug.com/638849
WTF_EXPORT PRINTF_FORMAT(1, 2) // NOLINT
void WTFLogAlways(const char* format, ...);
namespace WTF {
#if !DCHECK_IS_ON()
#define WTF_CREATE_SCOPED_LOGGER(...) ((void)0)
#define WTF_CREATE_SCOPED_LOGGER_IF(...) ((void)0)
#define WTF_APPEND_SCOPED_LOGGER(...) ((void)0)
#else
// ScopedLogger wraps log messages in parentheses, with indentation proportional
// to the number of instances. This makes it easy to see the flow of control in
// the output, particularly when instrumenting recursive functions.
//
// NOTE: This class is a debugging tool, not intended for use by checked-in
// code. Please do not remove it.
//
class WTF_EXPORT ScopedLogger {
WTF_MAKE_NONCOPYABLE(ScopedLogger);
public:
// The first message is passed to the constructor. Additional messages for
// the same scope can be added with log(). If condition is false, produce no
// output and do not create a scope.
PRINTF_FORMAT(3, 4) ScopedLogger(bool condition, const char* format, ...);
~ScopedLogger();
PRINTF_FORMAT(2, 3) void Log(const char* format, ...);
private:
FRIEND_TEST_ALL_PREFIXES(AssertionsTest, ScopedLogger);
using PrintFunctionPtr = void (*)(const char* format, va_list args);
// Note: not thread safe.
static void SetPrintFuncForTests(PrintFunctionPtr);
void Init(const char* format, va_list args);
void WriteNewlineIfNeeded();
void Indent();
void Print(const char* format, ...);
void PrintIndent();
static ScopedLogger*& Current();
ScopedLogger* const parent_;
bool multiline_; // The ')' will go on the same line if there is only one
// entry.
static PrintFunctionPtr print_func_;
};
#define WTF_CREATE_SCOPED_LOGGER(name, ...) \
WTF::ScopedLogger name(true, __VA_ARGS__)
#define WTF_CREATE_SCOPED_LOGGER_IF(name, condition, ...) \
WTF::ScopedLogger name(condition, __VA_ARGS__)
#define WTF_APPEND_SCOPED_LOGGER(name, ...) (name.Log(__VA_ARGS__))
#endif // !DCHECK_IS_ON()
} // namespace WTF
#define DCHECK_AT(assertion, file, line) \
LAZY_STREAM(logging::LogMessage(file, line, #assertion).stream(), \
DCHECK_IS_ON() ? !(assertion) : false)
......
......@@ -6,7 +6,6 @@
#include "platform/wtf/text/StringBuilder.h"
#include "testing/gtest/include/gtest/gtest.h"
#include <stdio.h>
namespace WTF {
......@@ -36,41 +35,4 @@ TEST(AssertionsTest, Assertions) {
EXPECT_DEATH_IF_SUPPORTED(SECURITY_CHECK(false), "");
};
#if DCHECK_IS_ON()
static const int kPrinterBufferSize = 256;
static char g_buffer[kPrinterBufferSize];
static StringBuilder g_builder;
static void Vprint(const char* format, va_list args) {
int written = vsnprintf(g_buffer, kPrinterBufferSize, format, args);
if (written > 0 && written < kPrinterBufferSize)
g_builder.Append(g_buffer);
}
TEST(AssertionsTest, ScopedLogger) {
ScopedLogger::SetPrintFuncForTests(Vprint);
{
WTF_CREATE_SCOPED_LOGGER(a, "a1");
{
WTF_CREATE_SCOPED_LOGGER_IF(b, false, "b1");
{
WTF_CREATE_SCOPED_LOGGER(c, "c");
{ WTF_CREATE_SCOPED_LOGGER(d, "d %d %s", -1, "hello"); }
}
WTF_APPEND_SCOPED_LOGGER(b, "b2");
}
WTF_APPEND_SCOPED_LOGGER(a, "a2 %.1f", 0.5);
}
EXPECT_EQ(
"( a1\n"
" ( c\n"
" ( d -1 hello )\n"
" )\n"
" a2 0.5\n"
")\n",
g_builder.ToString());
};
#endif // DCHECK_IS_ON()
} // namespace WTF
......@@ -110,6 +110,8 @@ component("wtf") {
"RetainPtr.h",
"SaturatedArithmetic.h",
"SaturatedArithmeticARM.h",
"ScopedLogger.cpp",
"ScopedLogger.h",
"SizeAssertions.h",
"SizeLimits.cpp",
"SpinLock.h",
......@@ -338,6 +340,7 @@ test("wtf_unittests") {
"PtrUtilTest.cpp",
"RefPtrTest.cpp",
"SaturatedArithmeticTest.cpp",
"ScopedLoggerTest.cpp",
"StringExtrasTest.cpp",
"StringHasherTest.cpp",
"TimeTest.cpp",
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/wtf/ScopedLogger.h"
#include "build/build_config.h"
#include "platform/wtf/Assertions.h"
#include "platform/wtf/ThreadSpecific.h"
#if DCHECK_IS_ON()
namespace WTF {
ScopedLogger::ScopedLogger(bool condition, const char* format, ...)
: parent_(condition ? Current() : 0), multiline_(false) {
if (!condition)
return;
va_list args;
va_start(args, format);
Init(format, args);
va_end(args);
}
ScopedLogger::~ScopedLogger() {
if (Current() == this) {
if (multiline_)
Indent();
else
Print(" ");
Print(")\n");
Current() = parent_;
}
}
void ScopedLogger::SetPrintFuncForTests(PrintFunctionPtr ptr) {
print_func_ = ptr;
};
void ScopedLogger::Init(const char* format, va_list args) {
Current() = this;
if (parent_)
parent_->WriteNewlineIfNeeded();
Indent();
Print("( ");
print_func_(format, args);
}
void ScopedLogger::WriteNewlineIfNeeded() {
if (!multiline_) {
Print("\n");
multiline_ = true;
}
}
void ScopedLogger::Indent() {
if (parent_) {
parent_->Indent();
PrintIndent();
}
}
void ScopedLogger::Log(const char* format, ...) {
if (Current() != this)
return;
va_list args;
va_start(args, format);
WriteNewlineIfNeeded();
Indent();
PrintIndent();
print_func_(format, args);
Print("\n");
va_end(args);
}
void ScopedLogger::Print(const char* format, ...) {
va_list args;
va_start(args, format);
print_func_(format, args);
va_end(args);
}
void ScopedLogger::PrintIndent() {
Print(" ");
}
ScopedLogger*& ScopedLogger::Current() {
DEFINE_THREAD_SAFE_STATIC_LOCAL(ThreadSpecific<ScopedLogger*>, ref, ());
return *ref;
}
ScopedLogger::PrintFunctionPtr ScopedLogger::print_func_ =
vprintf_stderr_common;
} // namespace WTF
#endif // DCHECK_IS_ON
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef WTF_ScopedLogger_h
#define WTF_ScopedLogger_h
#include "base/gtest_prod_util.h"
#include "base/logging.h"
#include "platform/wtf/Noncopyable.h"
#include "platform/wtf/WTFExport.h"
namespace WTF {
#if !DCHECK_IS_ON()
#define WTF_CREATE_SCOPED_LOGGER(...) ((void)0)
#define WTF_CREATE_SCOPED_LOGGER_IF(...) ((void)0)
#define WTF_APPEND_SCOPED_LOGGER(...) ((void)0)
#else
// ScopedLogger wraps log messages in parentheses, with indentation proportional
// to the number of instances. This makes it easy to see the flow of control in
// the output, particularly when instrumenting recursive functions.
//
// NOTE: This class is a debugging tool, not intended for use by checked-in
// code. Please do not remove it.
//
class WTF_EXPORT ScopedLogger {
WTF_MAKE_NONCOPYABLE(ScopedLogger);
public:
// The first message is passed to the constructor. Additional messages for
// the same scope can be added with log(). If condition is false, produce no
// output and do not create a scope.
PRINTF_FORMAT(3, 4) ScopedLogger(bool condition, const char* format, ...);
~ScopedLogger();
PRINTF_FORMAT(2, 3) void Log(const char* format, ...);
private:
FRIEND_TEST_ALL_PREFIXES(ScopedLoggerTest, ScopedLogger);
using PrintFunctionPtr = void (*)(const char* format, va_list args);
// Note: not thread safe.
static void SetPrintFuncForTests(PrintFunctionPtr);
void Init(const char* format, va_list args);
void WriteNewlineIfNeeded();
void Indent();
void Print(const char* format, ...);
void PrintIndent();
static ScopedLogger*& Current();
ScopedLogger* const parent_;
bool multiline_; // The ')' will go on the same line if there is only one
// entry.
static PrintFunctionPtr print_func_;
};
#define WTF_CREATE_SCOPED_LOGGER(name, ...) \
WTF::ScopedLogger name(true, __VA_ARGS__)
#define WTF_CREATE_SCOPED_LOGGER_IF(name, condition, ...) \
WTF::ScopedLogger name(condition, __VA_ARGS__)
#define WTF_APPEND_SCOPED_LOGGER(name, ...) (name.Log(__VA_ARGS__))
#endif // !DCHECK_IS_ON()
} // namespace WTF
#endif // WTF_ScopedLogger_h
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "platform/wtf/ScopedLogger.h"
#include "platform/wtf/text/StringBuilder.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace WTF {
#if DCHECK_IS_ON()
static const int kPrinterBufferSize = 256;
static char g_buffer[kPrinterBufferSize];
static StringBuilder g_builder;
static void Vprint(const char* format, va_list args) {
int written = vsnprintf(g_buffer, kPrinterBufferSize, format, args);
if (written > 0 && written < kPrinterBufferSize)
g_builder.Append(g_buffer);
}
TEST(ScopedLoggerTest, ScopedLogger) {
ScopedLogger::SetPrintFuncForTests(Vprint);
{
WTF_CREATE_SCOPED_LOGGER(a, "a1");
{
WTF_CREATE_SCOPED_LOGGER_IF(b, false, "b1");
{
WTF_CREATE_SCOPED_LOGGER(c, "c");
{ WTF_CREATE_SCOPED_LOGGER(d, "d %d %s", -1, "hello"); }
}
WTF_APPEND_SCOPED_LOGGER(b, "b2");
}
WTF_APPEND_SCOPED_LOGGER(a, "a2 %.1f", 0.5);
}
EXPECT_EQ(
"( a1\n"
" ( c\n"
" ( d -1 hello )\n"
" )\n"
" a2 0.5\n"
")\n",
g_builder.ToString());
};
#endif // DCHECK_IS_ON()
} // namespace WTF
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment