diff options
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/escape-char.cc | 22 | ||||
-rw-r--r-- | src/libutil/escape-char.hh | 22 | ||||
-rw-r--r-- | src/libutil/meson.build | 2 |
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', |