about summary refs log tree commit diff
path: root/src/libutil/util.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil/util.cc')
-rw-r--r--src/libutil/util.cc35
1 files changed, 35 insertions, 0 deletions
diff --git a/src/libutil/util.cc b/src/libutil/util.cc
index 14aab7cded32..0600352ff537 100644
--- a/src/libutil/util.cc
+++ b/src/libutil/util.cc
@@ -453,6 +453,7 @@ void printMsg_(Verbosity level, const FormatOrString & fs)
     else if (logType == ltEscapes && level != lvlInfo)
         prefix = "\033[" + escVerbosity(level) + "s";
     string s = (format("%1%%2%\n") % prefix % fs.s).str();
+    if (!isatty(STDERR_FILENO)) s = filterANSIEscapes(s);
     writeToStderr(s);
 }
 
@@ -1106,4 +1107,38 @@ void ignoreException()
 }
 
 
+string filterANSIEscapes(const string & s, bool nixOnly)
+{
+    string t, r;
+    enum { stTop, stEscape, stCSI } state = stTop;
+    for (auto c : s) {
+        if (state == stTop) {
+            if (c == '\e') {
+                state = stEscape;
+                r = c;
+            } else
+                t += c;
+        } else if (state == stEscape) {
+            r += c;
+            if (c == '[')
+                state = stCSI;
+            else {
+                t += r;
+                state = stTop;
+            }
+        } else {
+            r += c;
+            if (c >= 0x40 && c != 0x7e) {
+                if (nixOnly && (c != 'p' && c != 'q' && c != 's' && c != 'a' && c != 'b'))
+                    t += r;
+                state = stTop;
+                r.clear();
+            }
+        }
+    }
+    t += r;
+    return t;
+}
+
+
 }