31#define __attribute__(X) 
   40extern int maximumLogLevel;
 
   43extern bool enableLoggingGlobally;
 
   44extern bool enableLoggingInContext;  
 
   47int fileLogLevel(
const char *file);
 
   48std::ostream &fileLogOutput(
const char *file);
 
   55    static int ostream_xalloc;
 
   56    static void setup_ostream_xalloc(std::ostream &);
 
   57    friend std::ostream &operator<<(std::ostream &, 
const OutputLogPrefix &);
 
   58    friend std::ostream &clearPrefix(std::ostream &out);
 
   61    mutable lock_t *lock = 
nullptr;
 
   66    static void indent(std::ostream &out);
 
 
   69void addInvalidateCallback(
void (*)(
void));
 
   70std::ostream &clearPrefix(std::ostream &out);
 
   73inline std::ostream &endl(std::ostream &out) {
 
   75    Detail::OutputLogPrefix::indent(out);
 
   78using IndentCtl::indent;
 
   80using IndentCtl::unindent;
 
   82inline bool fileLogLevelIsAtLeast(
const char *file, 
int level) {
 
   85    if (Detail::maximumLogLevel < level) {
 
   89    return Detail::fileLogLevel(file) >= level;
 
   93void addDebugSpec(
const char *spec);
 
   95inline bool verbose() { 
return Detail::verbosity > 0; }
 
   96inline int verbosity() { 
return Detail::verbosity; }
 
   97inline bool enableLogging() {
 
   98    return Detail::enableLoggingGlobally || Detail::enableLoggingInContext;
 
  100void increaseVerbosity();
 
  104#ifndef MAX_LOGGING_LEVEL 
  106#define MAX_LOGGING_LEVEL 10 
  111    ((N) <= MAX_LOGGING_LEVEL && ::Log::fileLogLevelIsAtLeast(__FILE__, N) && \ 
  112     ::Log::enableLogging()) 
  114    (LOGGING(N) ? ::Log::Detail::fileLogOutput(__FILE__)                  \ 
  115                      << ::Log::Detail::OutputLogPrefix(__FILE__, N) << X \ 
  116                      << ::Log::Detail::clearPrefix << std::endl          \ 
  118#define LOG1(X) LOGN(1, X) 
  119#define LOG2(X) LOGN(2, X) 
  120#define LOG3(X) LOGN(3, X) 
  121#define LOG4(X) LOGN(4, X) 
  122#define LOG5(X) LOGN(5, X) 
  123#define LOG6(X) LOGN(6, X) 
  124#define LOG7(X) LOGN(7, X) 
  125#define LOG8(X) LOGN(8, X) 
  126#define LOG9(X) LOGN(9, X) 
  128#define LOGN_UNINDENT(N) \ 
  129    (LOGGING(N) ? ::Log::Detail::fileLogOutput(__FILE__) << IndentCtl::unindent : std::clog) 
  130#define LOG1_UNINDENT LOGN_UNINDENT(1) 
  131#define LOG2_UNINDENT LOGN_UNINDENT(2) 
  132#define LOG3_UNINDENT LOGN_UNINDENT(3) 
  133#define LOG4_UNINDENT LOGN_UNINDENT(4) 
  134#define LOG5_UNINDENT LOGN_UNINDENT(5) 
  135#define LOG6_UNINDENT LOGN_UNINDENT(6) 
  136#define LOG7_UNINDENT LOGN_UNINDENT(7) 
  137#define LOG8_UNINDENT LOGN_UNINDENT(8) 
  138#define LOG9_UNINDENT LOGN_UNINDENT(9) 
  140#define LOG_FEATURE(TAG, N, X)                                             \ 
  141    ((N) <= MAX_LOGGING_LEVEL && ::Log::fileLogLevelIsAtLeast(TAG, N)      \ 
  142         ? ::Log::Detail::fileLogOutput(TAG)                               \ 
  143               << ::Log::Detail::OutputLogPrefix(TAG, N) << X << std::endl \ 
  146#define P4C_ERROR(X) (std::clog << "ERROR: " << X << std::endl) 
  147#define P4C_WARNING(X) (::Log::verbose() ? std::clog << "WARNING: " << X << std::endl : std::clog) 
  148#define ERRWARN(C, X) ((C) ? P4C_ERROR(X) : P4C_WARNING(X)) 
  151static inline std::ostream &operator<<(std::ostream &out,
 
  152                                       std::function<std::ostream &(std::ostream &)> fn) {
 
  160std::ostream &format_container(std::ostream &out, 
const Cont &container, 
char lbrace, 
char rbrace) {
 
  161    std::vector<std::string> elems;
 
  162    bool foundnl = 
false;
 
  163    for (
auto &el : container) {
 
  164        std::stringstream tmp;
 
  166        elems.emplace_back(tmp.str());
 
  167        if (!foundnl) foundnl = elems.back().find(
'\n') != std::string::npos;
 
  170        for (
auto &el : elems) {
 
  171            out << Log::endl << Log::indent;
 
  172            for (
auto &ch : el) {
 
  178            out << Log::unindent;
 
  181        const char *sep = 
" ";
 
  183        for (
auto &el : elems) {
 
  187        out << (sep + 1) << rbrace;
 
  194std::ostream &operator<<(std::ostream &out, 
const std::vector<T> &vec) {
 
  195    return format_container(out, vec, 
'[', 
']');
 
  199std::ostream &operator<<(std::ostream &out, 
const std::set<T> &set) {
 
  200    return format_container(out, set, 
'(', 
')');