diff shasum.py @ 21:f2d634270e1c

Refactor: parse a line of a digest file within a dedicated funcion
author Franz Glasner <fzglas.hg@dom66.de>
date Sat, 05 Dec 2020 13:32:00 +0100
parents 8f0241ed4a00
children 6bdfc5ad4656
line wrap: on
line diff
--- a/shasum.py	Sat Dec 05 12:54:44 2020 +0100
+++ b/shasum.py	Sat Dec 05 13:32:00 2020 +0100
@@ -138,24 +138,11 @@
     :rtype: tuple(str, str, str)
 
     """
-    # determine checkfile format (BSD or coreutils)
-    # BSD?
-    mo = re.search(r"\A(\S+)\s*\((.*)\)\s*=\s*(.+)\n?\Z", line)
-    if mo:
-        tag = mo.group(1)
-        algo = algotag2algotype(tag)
-        fn = mo.group(2)
-        digest = mo.group(3)
-    else:
-        mo = re.search(r"([^\ ]+) [\*\ ]?(.+)\n?\Z", line)
-        if mo:
-            tag = opts.algorithm[1]
-            algo = opts.algorithm[0]
-            fn = mo.group(2)
-            digest = mo.group(1)
-        else:
-            raise ValueError(
-                "improperly formatted digest line: {}".format(line))
+    parts = parse_digest_line(opts, line)
+    if not parts:
+        raise ValueError(
+            "improperly formatted digest line: {}".format(line))
+    tag, algo, fn, digest = parts
     try:
         with open(fn, "rb") as input:
             d = compute_digest(algo, input)
@@ -167,6 +154,39 @@
         return ("missing", fn, tag)
 
 
+def parse_digest_line(opts, line):
+    """Parse a `line` of a digest file and return its parts.
+
+    :return: a tuple of the normalized algorithm tag, the algorithm
+             constructor, the filename and the hex digest;
+             if `line` cannot be parsed successfully `None` is returned
+    :rtype: tuple(str, obj, str, str) or None
+
+    Handles coreutils and BSD-style file formats.
+
+    """
+    # determine checkfile format (BSD or coreutils)
+    # BSD?
+    mo = re.search(r"\A(\S+)\s*\((.*)\)\s*=\s*(.+)\n?\Z", line)
+    if mo:
+        # (tag, algorithm, filename, digest)
+        return (mo.group(1),
+                algotag2algotype(mo.group(1)),
+                mo.group(2),
+                mo.group(3))
+    else:
+        # coreutils?
+        mo = re.search(r"([^\ ]+) [\*\ ]?(.+)\n?\Z", line)
+        if mo:
+            # (tag, algorithm, filename, digest)
+            return (opts.algorithm[1],
+                    opts.algorithm[0],
+                    mo.group(2),
+                    mo.group(1))
+        else:
+            return None
+
+
 def argv2algo(s):
     """Convert a commane line algorithm specifier into a tuple with the
     type/factory of the digest and the algorithms tag for output purposes.