diff cutils/util/__init__.py @ 372:bfe1160fbfd3

treesum: Make ERROR outputs more consistent: use native paths where possible
author Franz Glasner <fzglas.hg@dom66.de>
date Sun, 13 Apr 2025 14:15:33 +0200
parents d5c920ace3cb
children 54a6d4534ef4
line wrap: on
line diff
--- a/cutils/util/__init__.py	Sat Apr 12 09:05:48 2025 +0200
+++ b/cutils/util/__init__.py	Sun Apr 13 14:15:33 2025 +0200
@@ -14,6 +14,7 @@
            "PY35",
            "n", "b", "u",
            "normalize_filename",
+           "escape_for_output",
            "argv2algo",
            "algotag2algotype",
            "algotag2digest_size",
@@ -44,10 +45,10 @@
             return s.encode(encoding)
         return s
 
-    def b(s, encoding="ascii"):
+    def b(s, encoding="ascii", errors="strict"):
         """Convert `s` to bytes"""
         if isinstance(s, unicode):       # noqa: F821 undefined name 'unicode'
-            return s.encode(encoding)
+            return s.encode(encoding, errors)
         return s
 
     def u(s, encoding="ascii"):
@@ -64,15 +65,32 @@
             return s.decode(encoding)
         return s
 
-    def b(s, encoding="ascii"):
+    def b(s, encoding="ascii", errors="strict"):
         """Convert `s` to bytes"""
         if isinstance(s, str):
-            return s.encode(encoding)
+            return s.encode(encoding, errors)
         return s
 
     u = n
 
 
+def escape_for_output(what):
+    """Escape `what` in such a way that the output can be safely written into
+    a line and/or column-oriented output file
+
+    """
+    if isinstance(what, bytes):
+        return (what.replace(b'\\', b"\\\\")
+                .replace(b'\n', b"\\x0a")
+                .replace(b'\r', b"\\x0d")
+                .replace(b'\t', b"\\x09"))
+    else:
+        return (what.replace(u'\\', u"\\\\")
+                .replace(u'\n', u"\\x0a")
+                .replace(u'\r', u"\\x0d")
+                .replace(u'\t', u"\\x09"))
+
+
 def default_algotag():
     """Determine the "best" default algorithm.