diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index ec639052b5..a93d6cb501 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -18,6 +18,15 @@ void sigintHandler(int signo) } +void setLogType(string lt) +{ + if (lt == "pretty") logType = ltPretty; + else if (lt == "escapes") logType = ltEscapes; + else if (lt == "flat") logType = ltFlat; + else throw UsageError("unknown log type"); +} + + /* Initialize and reorder arguments, then call the actual argument processor. */ static void initAndRun(int argc, char * * argv) @@ -44,6 +53,10 @@ static void initAndRun(int argc, char * * argv) if (sigaction(SIGINT, &act, &oact)) throw SysError("installing handler for SIGINT"); + /* Process the NIX_LOG_TYPE environment variable. */ + char * lt = getenv("NIX_LOG_TYPE"); + if (lt) setLogType(lt); + /* Put the arguments in a vector. */ Strings args, remaining; while (argc--) args.push_back(*argv++); @@ -72,7 +85,11 @@ static void initAndRun(int argc, char * * argv) string arg = *i; if (arg == "--verbose" || arg == "-v") verbosity = (Verbosity) ((int) verbosity + 1); - else if (arg == "--build-output" || arg == "-B") + else if (arg == "--log-type") { + ++i; + if (i == args.end()) throw UsageError("`--log-type' requires an argument"); + setLogType(*i); + } else if (arg == "--build-output" || arg == "-B") buildVerbosity = lvlError; /* lowest */ else if (arg == "--help") { printHelp(); diff --git a/src/libutil/util.cc b/src/libutil/util.cc index 3a6914cba1..768acf811c 100644 --- a/src/libutil/util.cc +++ b/src/libutil/util.cc @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -223,6 +224,7 @@ void writeStringToFile(const Path & path, const string & s) } +LogType logType = ltPretty; Verbosity verbosity = lvlError; static int nestingLevel = 0; @@ -236,13 +238,28 @@ Nest::Nest() Nest::~Nest() { - if (nest) nestingLevel--; + if (nest) { + nestingLevel--; + if (logType == ltEscapes) + cerr << "\033[q"; + } +} + + +static string escVerbosity(Verbosity level) +{ + int l = (int) level; + ostringstream st; + st << l; + return st.str(); } void Nest::open(Verbosity level, const format & f) { if (level <= verbosity) { + if (logType == ltEscapes) + cerr << "\033[" << escVerbosity(level) << "p"; printMsg_(level, f); nest = true; nestingLevel++; @@ -254,10 +271,13 @@ void printMsg_(Verbosity level, const format & f) { checkInterrupt(); if (level > verbosity) return; - string spaces; - for (int i = 0; i < nestingLevel; i++) - spaces += "| "; - cerr << format("%1%%2%\n") % spaces % f.str(); + string prefix; + if (logType == ltPretty) + for (int i = 0; i < nestingLevel; i++) + prefix += "| "; + else if (logType == ltEscapes && level != lvlInfo) + prefix = "\033[" + escVerbosity(level) + "s"; + cerr << format("%1%%2%\n") % prefix % f.str(); } diff --git a/src/libutil/util.hh b/src/libutil/util.hh index 34fff003b8..ac96d7fc1a 100644 --- a/src/libutil/util.hh +++ b/src/libutil/util.hh @@ -100,6 +100,13 @@ void writeStringToFile(const Path & path, const string & s); /* Messages. */ + +typedef enum { + ltPretty, /* nice, nested output */ + ltEscapes, /* nesting indicated using escape codes (for log2xml) */ + ltFlat /* no nesting */ +} LogType; + typedef enum { lvlError, lvlInfo, @@ -109,7 +116,8 @@ typedef enum { lvlVomit } Verbosity; -extern Verbosity verbosity; /* supress msgs > this */ +extern LogType logType; +extern Verbosity verbosity; /* suppress msgs > this */ class Nest {