aboutsummaryrefslogtreecommitdiff
path: root/src/libutil
diff options
context:
space:
mode:
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/escape-char.cc22
-rw-r--r--src/libutil/escape-char.hh22
-rw-r--r--src/libutil/meson.build2
3 files changed, 46 insertions, 0 deletions
diff --git a/src/libutil/escape-char.cc b/src/libutil/escape-char.cc
new file mode 100644
index 000000000..132260286
--- /dev/null
+++ b/src/libutil/escape-char.cc
@@ -0,0 +1,22 @@
+#include <boost/io/ios_state.hpp>
+#include <iomanip>
+#include <iostream>
+
+#include "escape-char.hh"
+
+namespace nix {
+
+std::ostream & operator<<(std::ostream & s, MaybeHexEscapedChar c)
+{
+ boost::io::ios_flags_saver _ifs(s);
+
+ if (isprint(c.c)) {
+ s << static_cast<char>(c.c);
+ } else {
+ s << "\\x" << std::hex << std::setfill('0') << std::setw(2)
+ << (static_cast<unsigned int>(c.c) & 0xff);
+ }
+ return s;
+}
+
+} // namespace nix
diff --git a/src/libutil/escape-char.hh b/src/libutil/escape-char.hh
new file mode 100644
index 000000000..c7bae7ec0
--- /dev/null
+++ b/src/libutil/escape-char.hh
@@ -0,0 +1,22 @@
+#pragma once
+#include <ostream>
+
+namespace nix {
+
+/**
+ * A struct that prints a debug representation of a character, like `\x1f` for
+ * non-printable characters, or the character itself for other characters.
+ *
+ * Note that these are suitable for human readable output, but further care is
+ * necessary to include them in C++ strings to avoid running into adjacent
+ * hex-like characters. (`"puppy\x1bdoggy"` parses as `"puppy" "\x1bd" "oggy"`
+ * and errors because 0x1bd is too big for a `char`.)
+ */
+struct MaybeHexEscapedChar
+{
+ char c;
+};
+
+std::ostream & operator<<(std::ostream & s, MaybeHexEscapedChar c);
+
+} // namespace nix
diff --git a/src/libutil/meson.build b/src/libutil/meson.build
index 8e4b5211d..cdfda3cf5 100644
--- a/src/libutil/meson.build
+++ b/src/libutil/meson.build
@@ -8,6 +8,7 @@ libutil_sources = files(
'config.cc',
'english.cc',
'error.cc',
+ 'escape-char.cc',
'exit.cc',
'experimental-features.cc',
'filesystem.cc',
@@ -49,6 +50,7 @@ libutil_headers = files(
'config.hh',
'english.hh',
'error.hh',
+ 'escape-char.hh',
'exit.hh',
'experimental-features.hh',
'experimental-features-json.hh',