Flesh out the logging implementation.
Add PLOG and ensure we have CHECK_STREQ and CHECK_STRNE to go with
the existing non-functional DCHECK_STREQ and DCHECK_STRNE.
This also gives us two different logging implementations, one for
the host that just uses std::cerr, and one for Android that uses
the Android log.
Also bring in the StringPrintf family.
Change-Id: I8e190c2c58f26b22ee76a2a87d447df6eb0fa73b
diff --git a/src/logging.h b/src/logging.h
index e1b99d6..24ffdbc 100644
--- a/src/logging.h
+++ b/src/logging.h
@@ -14,18 +14,35 @@
#ifndef ART_SRC_LOGGING_H_
#define ART_SRC_LOGGING_H_
-#include <cstdlib>
+#include <cerrno>
+#include <cstring>
#include <iostream> // NOLINT
-#include "src/macros.h"
+#include <sstream>
+#include "log_severity.h"
+#include "macros.h"
#define CHECK(x) \
- if (!(x)) LogMessageFatal(__FILE__, __LINE__).stream() << "Check failed: " #x
+ if (!(x)) \
+ LogMessage(__FILE__, __LINE__, FATAL, -1).stream() << "Check failed: " #x
+
#define CHECK_EQ(x, y) CHECK((x) == (y))
#define CHECK_NE(x, y) CHECK((x) != (y))
#define CHECK_LE(x, y) CHECK((x) <= (y))
#define CHECK_LT(x, y) CHECK((x) < (y))
#define CHECK_GE(x, y) CHECK((x) >= (y))
#define CHECK_GT(x, y) CHECK((x) > (y))
+#define CHECK_STREQ(s1, s2) CHECK_STROP(s1, s2, true)
+#define CHECK_STRNE(s1, s2) CHECK_STROP(s1, s2, false)
+
+#define CHECK_STROP(s1, s2, sense) \
+ do { \
+ if ((strcmp(s1, s2) == 0) != sense) { \
+ LOG(FATAL) << "Check failed: " \
+ << "\"" << s1 << "\"" \
+ << (sense ? " == " : " != ") \
+ << "\"" << s2 << "\""; \
+ } \
+ } while (false)
#ifndef NDEBUG
@@ -36,6 +53,8 @@
#define DCHECK_LT(x, y) CHECK_LT(x, y)
#define DCHECK_GE(x, y) CHECK_GE(x, y)
#define DCHECK_GT(x, y) CHECK_GT(x, y)
+#define DCHECK_STREQ(s1, s2) CHECK_STREQ(s1, s2)
+#define DCHECK_STRNE(s1, s2) CHECK_STRNE(s1, s2)
#else // NDEBUG
@@ -71,33 +90,29 @@
while (false) \
CHECK_STREQ(str1, str2)
+#define DCHECK_STRNE(str1, str2) \
+ while (false) \
+ CHECK_STRNE(str1, str2)
+
#endif
-#define LOG_INFO LogMessage(__FILE__, __LINE__)
-#define LOG_WARN LOG_INFO // TODO
-#define LOG_FATAL LogMessageFatal(__FILE__, __LINE__)
-#define LOG(severity) LOG_ ## severity.stream()
+#define LOG(severity) LogMessage(__FILE__, __LINE__, severity, -1).stream()
+#define PLOG(severity) LogMessage(__FILE__, __LINE__, severity, errno).stream()
+
#define LG LOG(INFO)
class LogMessage {
public:
- LogMessage(const char* file, int line) {}
- ~LogMessage() { std::cerr << "\n"; }
- std::ostream& stream() { return std::cerr; }
- private:
- DISALLOW_COPY_AND_ASSIGN(LogMessage);
-};
+ LogMessage(const char* file, int line, LogSeverity severity, int error);
+ ~LogMessage();
+ std::ostream& stream();
-class LogMessageFatal : public LogMessage {
- public:
- LogMessageFatal(const char* file, int line)
- : LogMessage(file, line) {}
- ~LogMessageFatal() {
- std::cerr << "\n";
- std::abort();
- }
private:
- DISALLOW_COPY_AND_ASSIGN(LogMessageFatal);
+ std::stringstream buffer_;
+ LogSeverity severity_;
+ int errno_;
+
+ DISALLOW_COPY_AND_ASSIGN(LogMessage);
};
#endif // ART_SRC_LOGGING_H_