[Scummvm-git-logs] scummvm master -> 0f46b3065473c1c69b7b95d4594effa0c6303b47

rvanlaar roland at rolandvanlaar.nl
Sun Aug 8 21:42:50 UTC 2021


This automated email contains information about 1 new commit which have been
pushed to the 'scummvm' repo located at https://github.com/scummvm/scummvm .

Summary:
0f46b30654 DEVTOOLS: COMPANION: punyencode strings


Commit: 0f46b3065473c1c69b7b95d4594effa0c6303b47
    https://github.com/scummvm/scummvm/commit/0f46b3065473c1c69b7b95d4594effa0c6303b47
Author: Roland van Laar (roland at rolandvanlaar.nl)
Date: 2021-08-08T23:42:01+02:00

Commit Message:
DEVTOOLS: COMPANION: punyencode strings

Adds the `str` subcommand:

./dumper-companion.py str STRING
    punyencode the string STRING
./dumper-companion.py str --stdin
    punyencode stdin

The HFS iso dumper is moved into it's own subcommand:

./dumper-companion.py iso -e encoding input_iso output_dir

Changed paths:
    devtools/dumper-companion.py


diff --git a/devtools/dumper-companion.py b/devtools/dumper-companion.py
index 6ee5a42e6e..d379eaf27c 100755
--- a/devtools/dumper-companion.py
+++ b/devtools/dumper-companion.py
@@ -1,19 +1,20 @@
 #!/usr/bin/env python3
 #
 # prerequisites: pip3 install machfs
-# This file contains tests. They can be run with $ pytest dumper-companion.py
-
-from typing import Tuple
+# This file contains tests. They can be run with:
+#  $ pytest dumper-companion.py
 
 import argparse
+import io
 from binascii import crc_hqx
 from pathlib import Path
 from struct import pack
+from typing import Any, List, Tuple
 
 import machfs
 
 
-def file_to_macbin(f: machfs.File, name:str, encoding:str ) -> bytes:
+def file_to_macbin(f: machfs.File, name: str, encoding: str) -> bytes:
     oldFlags = f.flags >> 8
     newFlags = f.flags & 8
     macbin = pack(
@@ -58,24 +59,41 @@ def escape_string(s: str) -> str:
     return "".join(new_name)
 
 
-def decode_name(s: str, encoding:str) -> str:
-    s = s.encode("mac_roman").decode(encoding)
+def punyencode(orig: str, encoding: str = "mac_roman") -> str:
+    s = orig.encode("mac_roman").decode(encoding)
     s = escape_string(s)
-    return s.encode("punycode").decode("ascii")
-
-def generate_punyencoded_path(destination_dir: Path, encoding:str, hpath: Tuple[str]) -> Path:
+    encoded = s.encode("punycode").decode("ascii")
+    # punyencoding adds an '-' at the end when there are no special chars
+    # don't use it for comparing
+    if orig != encoded[:-1]:
+        return "xn--" + encoded
+    return orig
+
+
+def encode_string(args: argparse.Namespace) -> None:
+    if args.string:
+        var = args.string
+    if args.stdin:
+        var = input()
+    print(punyencode(var))
+
+
+def generate_punyencoded_path(
+    destination_dir: Path, encoding: str, hpath: Tuple[str]
+) -> Path:
+    """Convert a filepath to a punyencoded one"""
     upath = destination_dir
 
     for el in hpath:
-        if decode_name(el, encoding=encoding) != el + "-":
-            decoded = decode_name(el, encoding=encoding)
-            upath /= "xn--" + decode_name(el, encoding=encoding)
-        else:
-            upath /= el
+        upath /= punyencode(el, encoding=encoding)
     return upath
 
 
-def extract_volume(source_volume: Path, destination_dir:Path, encoding:str) -> None:
+def extract_volume(args: argparse.Namespace) -> None:
+    source_volume: Path = args.src
+    destination_dir: Path = args.dir
+    encoding: str = args.e
+
     print(f"Loading {source_volume} ...")
     vol = machfs.Volume()
     vol.read(source_volume.read_bytes())
@@ -95,25 +113,81 @@ def extract_volume(source_volume: Path, destination_dir:Path, encoding:str) -> N
             upath.write_bytes(file)
 
 
-if __name__ == "__main__":
-    args = argparse.ArgumentParser()
-    args.add_argument(
+def generate_parser() -> argparse.ArgumentParser:
+    """
+    Generate the parser
+
+    The parser is split into multiple subparsers.
+    One for each mode we support.
+
+    Each subparser has a default function that handles that mode.
+    """
+    parser = argparse.ArgumentParser()
+    subparsers = parser.add_subparsers()
+    parser_iso = subparsers.add_parser("iso", help="Dump hfs isos")
+
+    parser_iso.add_argument(
         "-e",
         metavar="ENCODING",
         type=str,
         default="mac_roman",
         help="String encoding (see https://docs.python.org/3/library/codecs.html#standard-encodings)",
     )
-    args.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
-    args.add_argument("dir", metavar="OUTPUT", type=Path, help="Destination folder")
-    parsed_args = args.parse_args()
+    parser_iso.add_argument("src", metavar="INPUT", type=Path, help="Disk image")
+    parser_iso.add_argument(
+        "dir", metavar="OUTPUT", type=Path, help="Destination folder"
+    )
+    parser_iso.set_defaults(func=extract_volume)
+
+    parser_str = subparsers.add_parser("str", help="Punyencode strings")
+    parser_str.add_argument(
+        "--stdin", action="store_true", help="Convert stdin to punycode"
+    )
+    parser_str.add_argument(
+        "string",
+        metavar="STRING",
+        type=str,
+        help="Convert string to punycode",
+        nargs="?",
+    )
+    parser_str.set_defaults(func=encode_string)
+
+    return parser
+
+
+if __name__ == "__main__":
+    parser = generate_parser()
+    args = parser.parse_args()
+    args.func(args)
+
+### Test functions
+
+
+def call_test_parser(input_args: List[str]) -> Any:
+    """Helper function to call the parser"""
+    parser = generate_parser()
+    args = parser.parse_args(input_args)
+    args.func(args)
+
+
+def test_encode_string(capsys):
+    call_test_parser(["str", "Icon\r"])
+    captured = capsys.readouterr()
+    assert captured.out == "xn--Icon-ea2f\n"
+
+
+def test_encode_stdin(capsys, monkeypatch):
+    monkeypatch.setattr("sys.stdin", io.StringIO("Icon\r"))
+    call_test_parser(["str", "--stdin"])
+    captured = capsys.readouterr()
+    assert captured.out == "xn--Icon-ea2f\n"
 
-    extract_volume(parsed_args.src, parsed_args.dir, parsed_args.e)
 
 def test_decode_name():
-    checks = [["Icon\r", "Icon-ea2f"]]
+    checks = [["Icon\r", "xn--Icon-ea2f"]]
     for input, expected in checks:
-        assert decode_name(input, "mac_roman") == expected
+        assert punyencode(input, "mac_roman") == expected
+
 
 def test_escape_string():
     checks = [["\r", "\x80\x8d"]]




More information about the Scummvm-git-logs mailing list