22#define __attribute__(X)
32extern int maximumLogLevel;
35extern bool enableLoggingGlobally;
36extern bool enableLoggingInContext;
39int fileLogLevel(
const char *file);
40std::ostream &fileLogOutput(
const char *file);
44class OutputLogPrefix {
47 static int ostream_xalloc;
48 static void setup_ostream_xalloc(std::ostream &);
49 friend std::ostream &operator<<(std::ostream &,
const OutputLogPrefix &);
50 friend std::ostream &clearPrefix(std::ostream &out);
53 mutable lock_t *lock =
nullptr;
56 OutputLogPrefix(
const char *f,
int l) : fn(f), level(l) {}
58 static void indent(std::ostream &out);
61void addInvalidateCallback(
void (*)(
void));
62std::ostream &clearPrefix(std::ostream &out);
65inline std::ostream &endl(std::ostream &out) {
67 Detail::OutputLogPrefix::indent(out);
70using ::P4::IndentCtl::indent;
72using ::P4::IndentCtl::unindent;
74inline bool fileLogLevelIsAtLeast(
const char *file,
int level) {
77 if (Detail::maximumLogLevel < level) {
81 return Detail::fileLogLevel(file) >= level;
85void addDebugSpec(
const char *spec);
87inline bool verbose() {
return Detail::verbosity > 0; }
88inline int verbosity() {
return Detail::verbosity; }
89inline bool enableLogging() {
90 return Detail::enableLoggingGlobally || Detail::enableLoggingInContext;
92void increaseVerbosity();
97#ifndef MAX_LOGGING_LEVEL
99#define MAX_LOGGING_LEVEL 10
103#define LOGGING_FEATURE(TAG, N) \
104 ((N) <= MAX_LOGGING_LEVEL && P4::Log::fileLogLevelIsAtLeast(TAG, N) && P4::Log::enableLogging())
105#define LOGGING(N) LOGGING_FEATURE(__FILE__, N)
108 (LOGGING(N) ? P4::Log::Detail::fileLogOutput(__FILE__) \
109 << P4::Log::Detail::OutputLogPrefix(__FILE__, N) << X \
110 << P4::Log::Detail::clearPrefix << std::endl \
112#define LOG1(X) LOGN(1, X)
113#define LOG2(X) LOGN(2, X)
114#define LOG3(X) LOGN(3, X)
115#define LOG4(X) LOGN(4, X)
116#define LOG5(X) LOGN(5, X)
117#define LOG6(X) LOGN(6, X)
118#define LOG7(X) LOGN(7, X)
119#define LOG8(X) LOGN(8, X)
120#define LOG9(X) LOGN(9, X)
122#define LOGN_UNINDENT(N) \
123 (LOGGING(N) ? P4::Log::Detail::fileLogOutput(__FILE__) << P4::IndentCtl::unindent : std::clog)
124#define LOG1_UNINDENT LOGN_UNINDENT(1)
125#define LOG2_UNINDENT LOGN_UNINDENT(2)
126#define LOG3_UNINDENT LOGN_UNINDENT(3)
127#define LOG4_UNINDENT LOGN_UNINDENT(4)
128#define LOG5_UNINDENT LOGN_UNINDENT(5)
129#define LOG6_UNINDENT LOGN_UNINDENT(6)
130#define LOG7_UNINDENT LOGN_UNINDENT(7)
131#define LOG8_UNINDENT LOGN_UNINDENT(8)
132#define LOG9_UNINDENT LOGN_UNINDENT(9)
134#define LOG_FEATURE(TAG, N, X) \
135 (LOGGING_FEATURE(TAG, N) ? P4::Log::Detail::fileLogOutput(TAG) \
136 << P4::Log::Detail::OutputLogPrefix(TAG, N) << X << std::endl \
139#define P4C_ERROR(X) (std::clog << "ERROR: " << X << std::endl)
140#define P4C_WARNING(X) (P4::Log::verbose() ? std::clog << "WARNING: " << X << std::endl : std::clog)
141#define ERRWARN(C, X) ((C) ? P4C_ERROR(X) : P4C_WARNING(X))
146static inline std::ostream &operator<<(std::ostream &out,
147 std::function<std::ostream &(std::ostream &)> fn) {
155std::ostream &
format_container(std::ostream &out,
const Cont &container,
char lbrace,
char rbrace) {
156 std::vector<std::string> elems;
157 bool foundnl =
false;
158 for (
auto &el : container) {
159 std::stringstream tmp;
161 elems.emplace_back(tmp.str());
162 if (!foundnl) foundnl = elems.back().find(
'\n') != std::string::npos;
165 for (
auto &el : elems) {
166 out << Log::endl << Log::indent;
167 for (
auto &ch : el) {
173 out << Log::unindent;
176 const char *sep =
" ";
178 for (
auto &el : elems) {
182 out << (sep + 1) << rbrace;
189std::ostream &operator<<(std::ostream &out,
const std::vector<T> &vec) {
194std::ostream &operator<<(std::ostream &out,
const std::set<T> &set) {
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:13
std::ostream & format_container(std::ostream &out, const Cont &container, char lbrace, char rbrace)
Definition log.h:155