summaryrefslogtreecommitdiff
path: root/tiger-compiler/lib/misc/escape.cc
diff options
context:
space:
mode:
authorMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
committerMartial Simon <msimon_fr@hotmail.com>2025-09-15 01:07:58 +0200
commit967be9e750221ab2ab783f95df79bb26d290a45e (patch)
tree6802900a5e975f9f68b169f0f503f040056d6952 /tiger-compiler/lib/misc/escape.cc
add: added projectsHEADmain
Diffstat (limited to 'tiger-compiler/lib/misc/escape.cc')
-rw-r--r--tiger-compiler/lib/misc/escape.cc60
1 files changed, 60 insertions, 0 deletions
diff --git a/tiger-compiler/lib/misc/escape.cc b/tiger-compiler/lib/misc/escape.cc
new file mode 100644
index 0000000..7585afb
--- /dev/null
+++ b/tiger-compiler/lib/misc/escape.cc
@@ -0,0 +1,60 @@
+/**
+ ** \file misc/escape.cc
+ ** \brief Implementation for misc/escape.hh.
+ **/
+
+#include <cctype>
+#include <iomanip>
+#include <ios>
+#include <unordered_map>
+
+#include <misc/escape.hh>
+
+namespace misc
+{
+ std::ostream& escaped::print(std::ostream& ostr) const
+ {
+ return escape_(ostr, pobj_str_);
+ }
+
+ std::ostream& escaped::escape_(std::ostream& o, const std::string& es) const
+ {
+ // For some reason yet to be found, when we use the locale for
+ // std::isprint, Valgrind goes berzerk. So we no longer do the
+ // following:
+ //
+ // static std::locale locale("");
+ //
+ // if (std::isprint(*p, locale))
+ std::ios_base::fmtflags flags = o.flags(std::ios_base::oct);
+ char fill = o.fill('0');
+
+ /* The GNU Assembler does not recognize `\a' as a valid
+ escape sequence, hence this explicit conversion to the
+ 007 octal character. For more information, see
+ http://sourceware.org/binutils/docs/as/Strings.html. */
+ static const std::unordered_map<char, std::string> escapes = {
+ {'\a', R"(\007)"}, {'\b', R"(\b)"}, {'\f', R"(\f)"},
+ {'\n', R"(\n)"}, {'\r', R"(\r)"}, {'\t', R"(\t)"},
+ {'\v', R"(\v)"}, {'\\', R"(\\)"}, {'\"', R"(\")"}};
+
+ for (const auto& p : es)
+ {
+ if (const auto&& it = escapes.find(p); it != escapes.end())
+ o << it->second;
+ else
+ {
+ if (std::isprint(p))
+ o << p;
+ else
+ o << "\\" << std::setw(3)
+ << static_cast<int>(static_cast<unsigned char>(p));
+ }
+ }
+
+ o.fill(fill);
+ o.flags(flags);
+ return o;
+ }
+
+} // namespace misc