changeset 20:f274504eafd0

Use Python argparse module instead of custom self-rolled argument parser.
author Matti Hamalainen <ccr@tnsp.org>
date Tue, 11 May 2021 17:13:38 +0300
parents 7c6eb57798bd
children 7ef08e05a5bf
files lxmldump.py
diffstat 1 files changed, 41 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/lxmldump.py	Tue May 11 16:15:16 2021 +0300
+++ b/lxmldump.py	Tue May 11 17:13:38 2021 +0300
@@ -13,6 +13,7 @@
 from pathlib import Path
 import xml.etree.ElementTree as xmlET
 import unicodedata
+import argparse
 
 assert sys.version_info >= (3, 7)
 
@@ -20,15 +21,6 @@
 ###
 ### Default settings
 ###
-pkk_cfg = {
-    "verbosity": 3,
-    "annotate": False,
-    "mode": 0,
-    "normalize": False,
-    "debug": False,
-}
-
-
 pkk_str_fmap = {
     "Fragment" : ["<", ">"],
 }
@@ -56,7 +48,7 @@
 ## Print string to stdout using normalized Unicode if enabled
 def pkk_print(smsg):
     try:
-        if pkk_cfg["normalize"]:
+        if pkk_cfg.normalize:
             sys.stdout.write(unicodedata.normalize("NFC", smsg))
         else:
             sys.stdout.write(smsg)
@@ -72,7 +64,7 @@
 
 ## Check value against current verbosity level
 def pkk_verbosity(lvl):
-    return pkk_cfg["verbosity"] >= lvl
+    return pkk_cfg.verbosity >= lvl
 
 
 ## Fatal error handler
@@ -109,7 +101,7 @@
         else:
             if isinstance(pnode.text, str):
                 ptext = pkk_str_clean(pnode.text).strip()
-                if pkk_cfg["annotate"] and isinstance(pnode.tag, str) and pnode.tag in pkk_str_fmap:
+                if pkk_cfg.annotate and isinstance(pnode.tag, str) and pnode.tag in pkk_str_fmap:
                     stmp += pkk_str_fmap[pnode.tag][0] + ptext + pkk_str_fmap[pnode.tag][1]
                 else:
                     stmp += ptext
@@ -214,82 +206,50 @@
 ###
 signal.signal(signal.SIGINT, pkk_signal_handler)
 
-
-### Check if we have arguments
-pkk_show_help = False
-pkk_filenames = [] 
-argc = 1
-while argc < len(sys.argv):
-    arg = sys.argv[argc]
+optparser = argparse.ArgumentParser(
+    description="lxmldump - Dump ISO/FDIS 1951 XML file data",
+    usage="%(prog)s [options] <input xml file(s)>",
+    epilog="\n\n"
+    )
 
-    needs_param = False
-    if argc + 1 < len(sys.argv):
-        param = sys.argv[argc + 1]
-    else:
-        param = None
+optparser.add_argument("filenames", action="extend", nargs="*",
+    type=str, metavar="filename", help="XML filename(s)")
 
-    # Check for option type arg
-    if arg[0:1] == "-":
-        oarg = arg
-        arg = arg.lstrip("-")
+optparser.add_argument("-d", "--dump",
+    action="store_const", const=1, default=0,
+    dest="mode", help="output as simple dump")
+
+optparser.add_argument("-x", "--xml",
+    action="store_const", const=2,
+    dest="mode", help="output as XML")
 
-        if arg == "help" or arg == "h":
-            pkk_show_help = True
-        elif arg == "dump" or arg == "d":
-            pkk_cfg["mode"] = 1
-        elif arg == "xml" or arg == "x":
-            pkk_cfg["mode"] = 2
-        elif arg == "normalize" or arg == "n":
-            pkk_cfg["normalize"] = True
-        elif arg == "annotate" or arg == "a":
-            pkk_cfg["annotate"] = True
-        elif arg == "p":
-            pkk_cfg["debug"] = True
-        elif arg == "verbosity" or arg == "v":
-            needs_param = True
-            pkk_cfg["verbosity"] = param
-        else:
-            pkk_fatal(u"Invalid option argument '{0}'.".format(oarg))
+optparser.add_argument("-n", "--normalize",
+    action="store_const", const=True, default=False,
+    dest="normalize", help="output NFC normalized Unicode")
+
+optparser.add_argument("-a", "--annotate",
+    action="store_const", const=True, default=False,
+    dest="annotate", help="annotate strings")
 
-        if needs_param and param == None:
-            pkk_fatal(u"Option '{0}' requires an argument.".format(oarg))
-    else:
-        # Non-option argument
-        pkk_filenames.append(arg)
+optparser.add_argument("-v", "--verbosity",
+    type=int, choices=range(0,4), default=3,
+    metavar="n",
+    dest="verbosity", help='set verbosity level (0-3, default: %(default)s)')
 
-    if needs_param:
-        argc += 2
-    else:
-        argc += 1
+optparser.add_argument("-p", "--debug",
+    action="store_const", const=True, default=False,
+    dest="debug", help=argparse.SUPPRESS)
 
 
-### Show help if requested
-if pkk_show_help or len(pkk_filenames) == 0:
-    print(u"lxmldump - Dump ISO/FDIS 1951 XML file data")
-    print(u"Usage: {0} <options> <input xml file(s)>".
-        format(str(Path(sys.argv[0]).name)))
-    print(u"")
-    print(u"       --help              Show this help")
-    print(u"  -d,  --dump              Output as simple dump")
-    print(u"  -x,  --xml               Output as XML")
-    print(u"  -n,  --normalize         Output NFC normalized Unicode")
-    print(u"  -a,  --annotate          Annotate strings")
-    print(u"  -v,  --verbosity <n>     Set verbosity level (0 - 3)")
-    print(u"")
+### Show help if needed
+pkk_cfg = optparser.parse_args()
+if len(pkk_cfg.filenames) == 0:
+    optparser.print_help()
     sys.exit(0)
 
 
-### Validate settings
-try:
-    pkk_cfg["verbosity"] = int(pkk_cfg["verbosity"])
-except Exception as e:
-    pkk_fatal(u"Verbosity level is not a valid integer.")
-if pkk_cfg["verbosity"] < 0 or pkk_cfg["verbosity"] > 3:
-    pkk_fatal(u"Invalid verbosity level value {0}.".format(pkk_cfg["verbosity"]))
-
-
 ### Handle each input file
-for filename in pkk_filenames:
+for filename in pkk_cfg.filenames:
     # Parse XML file into element tree
     try:
         uxml = xmlET.parse(filename)
@@ -301,19 +261,19 @@
         xroot = uxml.getroot()
         for dnode in xroot.findall("./DictionaryEntry"):
 
-            if pkk_cfg["debug"] and dnode.attrib["identifier"] not in pkk_debug_list:
+            if pkk_cfg.debug and dnode.attrib["identifier"] not in pkk_debug_list:
                 continue
 
-            if pkk_cfg["mode"] == 0:
+            if pkk_cfg.mode == 0:
                 try:
                     pkk_output_node(0, dnode)
                 except Exception as e:
                     pkk_dump_recursive(0, dnode)
                     print(str(e))
                     sys.exit(0)
-            elif pkk_cfg["mode"] == 1:
+            elif pkk_cfg.mode == 1:
                 pkk_dump_recursive(0, dnode)
-            elif pkk_cfg["mode"] == 2:
+            elif pkk_cfg.mode == 2:
                 pkk_print(str(xmlET.tostring(dnode, encoding="utf8")) + "\n")
             else:
                 pkk_fatal("Invalid operation mode?")