Merge "Support base::logging on Windows."
This commit is contained in:
commit
9616e82988
4 changed files with 102 additions and 23 deletions
|
@ -18,11 +18,13 @@ LOCAL_PATH := $(call my-dir)
|
|||
|
||||
libbase_src_files := \
|
||||
file.cpp \
|
||||
logging.cpp \
|
||||
stringprintf.cpp \
|
||||
strings.cpp \
|
||||
|
||||
libbase_test_src_files := \
|
||||
file_test.cpp \
|
||||
logging_test.cpp \
|
||||
stringprintf_test.cpp \
|
||||
strings_test.cpp \
|
||||
test_main.cpp \
|
||||
|
@ -38,7 +40,7 @@ libbase_cppflags := \
|
|||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libbase
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_SRC_FILES := $(libbase_src_files) logging.cpp
|
||||
LOCAL_SRC_FILES := $(libbase_src_files)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
|
||||
LOCAL_CPPFLAGS := $(libbase_cppflags)
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
|
||||
|
@ -61,9 +63,6 @@ include $(BUILD_SHARED_LIBRARY)
|
|||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libbase
|
||||
LOCAL_SRC_FILES := $(libbase_src_files)
|
||||
ifneq ($(HOST_OS),windows)
|
||||
LOCAL_SRC_FILES += logging.cpp
|
||||
endif
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
|
||||
LOCAL_CPPFLAGS := $(libbase_cppflags)
|
||||
LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/include
|
||||
|
@ -85,7 +84,7 @@ include $(BUILD_HOST_SHARED_LIBRARY)
|
|||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libbase_test
|
||||
LOCAL_CLANG := true
|
||||
LOCAL_SRC_FILES := $(libbase_test_src_files) logging_test.cpp
|
||||
LOCAL_SRC_FILES := $(libbase_test_src_files)
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_CPPFLAGS := $(libbase_cppflags)
|
||||
LOCAL_SHARED_LIBRARIES := libbase
|
||||
|
@ -97,9 +96,6 @@ include $(BUILD_NATIVE_TEST)
|
|||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := libbase_test
|
||||
LOCAL_SRC_FILES := $(libbase_test_src_files)
|
||||
ifneq ($(HOST_OS),windows)
|
||||
LOCAL_SRC_FILES += logging_test.cpp
|
||||
endif
|
||||
LOCAL_C_INCLUDES := $(LOCAL_PATH)
|
||||
LOCAL_CPPFLAGS := $(libbase_cppflags)
|
||||
LOCAL_SHARED_LIBRARIES := libbase
|
||||
|
|
|
@ -27,12 +27,19 @@
|
|||
|
||||
#include <iostream>
|
||||
#include <limits>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <mutex>
|
||||
#else
|
||||
#define NOGDI // Suppress the evil ERROR macro.
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "base/macros.h"
|
||||
#include "base/strings.h"
|
||||
#include "cutils/threads.h"
|
||||
|
||||
|
@ -45,10 +52,79 @@
|
|||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
namespace {
|
||||
#ifndef _WIN32
|
||||
using std::mutex;
|
||||
using std::lock_guard;
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
const char* getprogname() {
|
||||
return program_invocation_short_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
#else
|
||||
const char* getprogname() {
|
||||
static bool first = true;
|
||||
static char progname[MAX_PATH] = {};
|
||||
|
||||
if (first) {
|
||||
// TODO(danalbert): This is a full path on Windows. Just get the basename.
|
||||
DWORD nchars = GetModuleFileName(nullptr, progname, sizeof(progname));
|
||||
DCHECK_GT(nchars, 0U);
|
||||
first = false;
|
||||
}
|
||||
|
||||
return progname;
|
||||
}
|
||||
|
||||
class mutex {
|
||||
public:
|
||||
mutex() {
|
||||
semaphore_ = CreateSemaphore(nullptr, 1, 1, nullptr);
|
||||
CHECK(semaphore_ != nullptr) << "Failed to create Mutex";
|
||||
}
|
||||
~mutex() {
|
||||
CloseHandle(semaphore_);
|
||||
}
|
||||
|
||||
void lock() {
|
||||
DWORD result = WaitForSingleObject(semaphore_, INFINITE);
|
||||
CHECK_EQ(result, WAIT_OBJECT_0) << GetLastError();
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
bool result = ReleaseSemaphore(semaphore_, 1, nullptr);
|
||||
CHECK(result);
|
||||
}
|
||||
|
||||
private:
|
||||
HANDLE semaphore_;
|
||||
};
|
||||
|
||||
template <typename LockT>
|
||||
class lock_guard {
|
||||
public:
|
||||
explicit lock_guard(LockT& lock) : lock_(lock) {
|
||||
lock_.lock();
|
||||
}
|
||||
|
||||
~lock_guard() {
|
||||
lock_.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
LockT& lock_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(lock_guard);
|
||||
};
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
namespace android {
|
||||
namespace base {
|
||||
|
||||
static std::mutex logging_lock;
|
||||
static mutex logging_lock;
|
||||
|
||||
#ifdef __ANDROID__
|
||||
static LogFunction gLogger = LogdLogger();
|
||||
|
@ -60,12 +136,6 @@ static bool gInitialized = false;
|
|||
static LogSeverity gMinimumLogSeverity = INFO;
|
||||
static std::unique_ptr<std::string> gProgramInvocationName;
|
||||
|
||||
#if defined(__GLIBC__)
|
||||
static const char* getprogname() {
|
||||
return program_invocation_short_name;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char* ProgramInvocationName() {
|
||||
if (gProgramInvocationName == nullptr) {
|
||||
gProgramInvocationName.reset(new std::string(getprogname()));
|
||||
|
@ -182,7 +252,7 @@ void InitLogging(char* argv[]) {
|
|||
}
|
||||
|
||||
void SetLogger(LogFunction&& logger) {
|
||||
std::lock_guard<std::mutex> lock(logging_lock);
|
||||
lock_guard<mutex> lock(logging_lock);
|
||||
gLogger = std::move(logger);
|
||||
}
|
||||
|
||||
|
@ -287,7 +357,7 @@ std::ostream& LogMessage::stream() {
|
|||
void LogMessage::LogLine(const char* file, unsigned int line, LogId id,
|
||||
LogSeverity severity, const char* message) {
|
||||
const char* tag = ProgramInvocationName();
|
||||
std::lock_guard<std::mutex> lock(logging_lock);
|
||||
lock_guard<mutex> lock(logging_lock);
|
||||
gLogger(id, severity, tag, file, line, message);
|
||||
}
|
||||
|
||||
|
|
|
@ -85,6 +85,9 @@ std::string make_log_pattern(android::base::LogSeverity severity,
|
|||
TEST(logging, LOG) {
|
||||
ASSERT_DEATH(LOG(FATAL) << "foobar", "foobar");
|
||||
|
||||
// We can't usefully check the output of any of these on Windows because we
|
||||
// don't have std::regex, but we can at least make sure we printed at least as
|
||||
// many characters are in the log message.
|
||||
{
|
||||
CapturedStderr cap;
|
||||
LOG(WARNING) << "foobar";
|
||||
|
@ -92,10 +95,13 @@ TEST(logging, LOG) {
|
|||
|
||||
std::string output;
|
||||
android::base::ReadFdToString(cap.fd(), &output);
|
||||
ASSERT_GT(output.length(), strlen("foobar"));
|
||||
|
||||
#if !defined(_WIN32)
|
||||
std::regex message_regex(
|
||||
make_log_pattern(android::base::WARNING, "foobar"));
|
||||
ASSERT_TRUE(std::regex_search(output, message_regex));
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -105,10 +111,13 @@ TEST(logging, LOG) {
|
|||
|
||||
std::string output;
|
||||
android::base::ReadFdToString(cap.fd(), &output);
|
||||
ASSERT_GT(output.length(), strlen("foobar"));
|
||||
|
||||
#if !defined(_WIN32)
|
||||
std::regex message_regex(
|
||||
make_log_pattern(android::base::INFO, "foobar"));
|
||||
ASSERT_TRUE(std::regex_search(output, message_regex));
|
||||
#endif
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -129,10 +138,13 @@ TEST(logging, LOG) {
|
|||
|
||||
std::string output;
|
||||
android::base::ReadFdToString(cap.fd(), &output);
|
||||
ASSERT_GT(output.length(), strlen("foobar"));
|
||||
|
||||
#if !defined(_WIN32)
|
||||
std::regex message_regex(
|
||||
make_log_pattern(android::base::DEBUG, "foobar"));
|
||||
ASSERT_TRUE(std::regex_search(output, message_regex));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -145,10 +157,13 @@ TEST(logging, PLOG) {
|
|||
|
||||
std::string output;
|
||||
android::base::ReadFdToString(cap.fd(), &output);
|
||||
ASSERT_GT(output.length(), strlen("foobar"));
|
||||
|
||||
#if !defined(_WIN32)
|
||||
std::regex message_regex(make_log_pattern(
|
||||
android::base::INFO, "foobar: No such file or directory"));
|
||||
ASSERT_TRUE(std::regex_search(output, message_regex));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,11 +176,14 @@ TEST(logging, UNIMPLEMENTED) {
|
|||
|
||||
std::string output;
|
||||
android::base::ReadFdToString(cap.fd(), &output);
|
||||
ASSERT_GT(output.length(), strlen("unimplemented"));
|
||||
|
||||
#if !defined(_WIN32)
|
||||
std::string expected_message =
|
||||
android::base::StringPrintf("%s unimplemented ", __PRETTY_FUNCTION__);
|
||||
std::regex message_regex(
|
||||
make_log_pattern(android::base::ERROR, expected_message.c_str()));
|
||||
ASSERT_TRUE(std::regex_search(output, message_regex));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,6 @@
|
|||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
|
||||
// No logging on Windows yet.
|
||||
#if !defined(_WIN32)
|
||||
android::base::InitLogging(argv, android::base::StderrLogger);
|
||||
#endif
|
||||
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue