imgtool: dumpinfo improvements

Fix trailer info dumping reads pad characters as values for status
Refactor printing styled texts and frames
Use isinstance() for type checking
Fold notice text depending on line length
Refactoring some parts for readability
Fix additional linting issues

Signed-off-by: Rustam Ismayilov <rustam.ismayilov@arm.com>
Change-Id: I741562bb70b18407bdd32e9c7391048faf6394c6
diff --git a/scripts/imgtool/dumpinfo.py b/scripts/imgtool/dumpinfo.py
index 6058fe1..5544657 100644
--- a/scripts/imgtool/dumpinfo.py
+++ b/scripts/imgtool/dumpinfo.py
@@ -17,13 +17,15 @@
 """
 Parse and print header, TLV area and trailer information of a signed image.
 """
-from imgtool import image
-import click
-import struct
-import yaml
 import os.path
+import struct
 import sys
 
+import click
+import yaml
+
+from imgtool import image
+
 HEADER_ITEMS = ("magic", "load_addr", "hdr_size", "protected_tlv_size",
                 "img_size", "flags", "version")
 TLV_TYPES = dict((value, key) for key, value in image.TLV_VALUES.items())
@@ -39,6 +41,59 @@
     0x1f, 0x8a, ])
 BOOT_MAGIC_SIZE = len(BOOT_MAGIC)
 _LINE_LENGTH = 60
+STATUS = {
+    '0x1': 'SET',
+    '0x2': 'BAD',
+    '0x3': 'UNSET',
+    '0x4': 'ANY',
+}
+
+
+def parse_enc(key_field_len):
+    if key_field_len is not None:
+        return "(len: {}, if BOOT_SWAP_SAVE_ENCTLV is unset)".format(hex(key_field_len))
+    else:
+        return "Image not encrypted"
+
+
+def parse_size(size_hex):
+    if size_hex == '0xffffffff':
+        return "unknown"
+    return size_hex + " octal: " + str(int(size_hex, 0))
+
+
+def parse_status(status_hex):
+    return f"{STATUS[status_hex]} ({status_hex})" if status_hex in STATUS else f"INVALID ({status_hex})"
+
+
+def parse_boot_magic(trailer_magic):
+    magic = ""
+    for i in range(BOOT_MAGIC_SIZE):
+        magic += "{0:#04x} ".format(trailer_magic[i])
+        if i == (BOOT_MAGIC_SIZE / 2 - 1):
+            magic += ("\n" + "             ")
+    return magic
+
+
+def print_in_frame(header_text, content):
+    sepc = " "
+    header = "#### " + header_text + sepc
+    post_header = "#" * (_LINE_LENGTH - len(header))
+    print(header + post_header)
+
+    print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
+    offset = (_LINE_LENGTH - len(content)) // 2
+    pre = "|" + (sepc * (offset - 1))
+    post = sepc * (_LINE_LENGTH - len(pre) - len(content) - 1) + "|"
+    print(pre, content, post, sep="")
+    print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
+    print("#" * _LINE_LENGTH)
+
+
+def print_in_row(row_text):
+    row_text = "#### " + row_text + " "
+    fill = "#" * (_LINE_LENGTH - len(row_text))
+    print(row_text + fill)
 
 
 def print_tlv_records(tlv_list):
@@ -66,10 +121,11 @@
 def dump_imginfo(imgfile, outfile=None, silent=False):
     """Parse a signed image binary and print/save the available information."""
     trailer_magic = None
-    swap_size = 0
-    swap_info = 0
-    copy_done = 0
-    image_ok = 0
+    #   set to INVALID by default
+    swap_size = 0x99
+    swap_info = 0x99
+    copy_done = 0x99
+    image_ok = 0x99
     trailer = {}
     key_field_len = None
 
@@ -92,16 +148,16 @@
 
     # Parsing the TLV area
     tlv_area = {"tlv_hdr_prot": {},
-                "tlvs_prot":    [],
-                "tlv_hdr":      {},
-                "tlvs":         []}
+                "tlvs_prot": [],
+                "tlv_hdr": {},
+                "tlvs": []}
     tlv_off = header["hdr_size"] + header["img_size"]
     protected_tlv_size = header["protected_tlv_size"]
 
     if protected_tlv_size != 0:
         _tlv_prot_head = struct.unpack(
-                            'HH',
-                            b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
+            'HH',
+            b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
         tlv_area["tlv_hdr_prot"]["magic"] = _tlv_prot_head[0]
         tlv_area["tlv_hdr_prot"]["tlv_tot"] = _tlv_prot_head[1]
         tlv_end = tlv_off + tlv_area["tlv_hdr_prot"]["tlv_tot"]
@@ -110,8 +166,8 @@
         # Iterating through the protected TLV area
         while tlv_off < tlv_end:
             tlv_type, tlv_len = struct.unpack(
-                                    'HH',
-                                    b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
+                'HH',
+                b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
             tlv_off += image.TLV_INFO_SIZE
             tlv_data = b[tlv_off:(tlv_off + tlv_len)]
             tlv_area["tlvs_prot"].append(
@@ -128,8 +184,8 @@
     # Iterating through the TLV area
     while tlv_off < tlv_end:
         tlv_type, tlv_len = struct.unpack(
-                                'HH',
-                                b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
+            'HH',
+            b[tlv_off:(tlv_off + image.TLV_INFO_SIZE)])
         tlv_off += image.TLV_INFO_SIZE
         tlv_data = b[tlv_off:(tlv_off + tlv_len)]
         tlv_area["tlvs"].append(
@@ -177,7 +233,7 @@
 
             # Encryption key 0/1
             if ((header["flags"] & image.IMAGE_F["ENCRYPTED_AES128"]) or
-               (header["flags"] & image.IMAGE_F["ENCRYPTED_AES256"])):
+                    (header["flags"] & image.IMAGE_F["ENCRYPTED_AES256"])):
                 # The image is encrypted
                 #    Estimated value of key_field_len is correct if
                 #    BOOT_SWAP_SAVE_ENCTLV is unset
@@ -192,7 +248,7 @@
             # sort_keys - from pyyaml 5.1
             yaml.dump(imgdata, outf, sort_keys=False)
 
-###############################################################################
+    ###############################################################################
 
     if silent:
         sys.exit(0)
@@ -200,9 +256,8 @@
     print("Printing content of signed image:", os.path.basename(imgfile), "\n")
 
     # Image header
-    str1 = "#### Image header (offset: 0x0) "
-    str2 = "#" * (_LINE_LENGTH - len(str1))
-    print(str1 + str2)
+    section_name = "Image header (offset: 0x0)"
+    print_in_row(section_name)
     for key, value in header.items():
         if key == "flags":
             if not value:
@@ -214,45 +269,34 @@
                         if flag_string:
                             flag_string += ("\n" + (" " * 20))
                         flag_string += "{} ({})".format(
-                                    flag, hex(image.IMAGE_F[flag]))
+                            flag, hex(image.IMAGE_F[flag]))
             value = flag_string
 
-        if type(value) != str:
+        if not isinstance(value, str):
             value = hex(value)
         print(key, ":", " " * (19 - len(key)), value, sep="")
     print("#" * _LINE_LENGTH)
 
     # Image payload
     _sectionoff = header["hdr_size"]
-    sepc = " "
-    str1 = "#### Payload (offset: {}) ".format(hex(_sectionoff))
-    str2 = "#" * (_LINE_LENGTH - len(str1))
-    print(str1 + str2)
-    print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
-    str1 = "FW image (size: {} Bytes)".format(hex(header["img_size"]))
-    numc = (_LINE_LENGTH - len(str1)) // 2
-    str2 = "|" + (sepc * (numc - 1))
-    str3 = sepc * (_LINE_LENGTH - len(str2) - len(str1) - 1) + "|"
-    print(str2, str1, str3, sep="")
-    print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
-    print("#" * _LINE_LENGTH)
+    frame_header_text = "Payload (offset: {})".format(hex(_sectionoff))
+    frame_content = "FW image (size: {} Bytes)".format(hex(header["img_size"]))
+    print_in_frame(frame_header_text, frame_content)
 
     # TLV area
     _sectionoff += header["img_size"]
     if protected_tlv_size != 0:
         # Protected TLV area
-        str1 = "#### Protected TLV area (offset: {}) ".format(hex(_sectionoff))
-        str2 = "#" * (_LINE_LENGTH - len(str1))
-        print(str1 + str2)
+        section_name = "Protected TLV area (offset: {})".format(hex(_sectionoff))
+        print_in_row(section_name)
         print("magic:    ", hex(tlv_area["tlv_hdr_prot"]["magic"]))
         print("area size:", hex(tlv_area["tlv_hdr_prot"]["tlv_tot"]))
         print_tlv_records(tlv_area["tlvs_prot"])
         print("#" * _LINE_LENGTH)
 
     _sectionoff += protected_tlv_size
-    str1 = "#### TLV area (offset: {}) ".format(hex(_sectionoff))
-    str2 = "#" * (_LINE_LENGTH - len(str1))
-    print(str1 + str2)
+    section_name = "TLV area (offset: {})".format(hex(_sectionoff))
+    print_in_row(section_name)
     print("magic:    ", hex(tlv_area["tlv_hdr"]["magic"]))
     print("area size:", hex(tlv_area["tlv_hdr"]["tlv_tot"]))
     print_tlv_records(tlv_area["tlvs"])
@@ -261,40 +305,24 @@
     if _img_pad_size:
         _sectionoff += tlv_area["tlv_hdr"]["tlv_tot"]
         _erased_val = b[_sectionoff]
-        str1 = "#### Image padding (offset: {}) ".format(hex(_sectionoff))
-        str2 = "#" * (_LINE_LENGTH - len(str1))
-        print(str1 + str2)
-        print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
-        str1 = "padding ({})".format(hex(_erased_val))
-        numc = (_LINE_LENGTH - len(str1)) // 2
-        str2 = "|" + (sepc * (numc - 1))
-        str3 = sepc * (_LINE_LENGTH - len(str2) - len(str1) - 1) + "|"
-        print(str2, str1, str3, sep="")
-        print("|", sepc * (_LINE_LENGTH - 2), "|", sep="")
-        print("#" * _LINE_LENGTH)
+        frame_header_text = "Image padding (offset: {})".format(hex(_sectionoff))
+        frame_content = "padding ({})".format(hex(_erased_val))
+        print_in_frame(frame_header_text, frame_content)
 
         # Image trailer
-        str1 = "#### Image trailer (offset: unknown) "
-        str2 = "#" * (_LINE_LENGTH - len(str1))
-        print(str1 + str2)
-        print("(Note: some field may not be used, \n"
-              " depending on the update strategy)\n")
-
+        section_name = "Image trailer (offset: unknown)"
+        print_in_row(section_name)
+        notice = "(Note: some fields may not be used, depending on the update strategy)\n"
+        notice = '\n'.join(notice[i:i + _LINE_LENGTH] for i in range(0, len(notice), _LINE_LENGTH))
+        print(notice)
         print("swap status: (len: unknown)")
-        if key_field_len is not None:
-            print("enc. keys:   (len: {}, if BOOT_SWAP_SAVE_ENCTLV is unset)"
-                  .format(hex(key_field_len)))
-        print("swap size:  ", hex(swap_size))
-        print("swap_info:  ", hex(swap_info))
-        print("copy_done:  ", hex(copy_done))
-        print("image_ok:   ", hex(image_ok))
-        print("boot magic:  ", end="")
-        for i in range(BOOT_MAGIC_SIZE):
-            print("{0:#04x}".format(trailer_magic[i]),  end=" ")
-            if i == (BOOT_MAGIC_SIZE / 2 - 1):
-                print("\n", end="             ")
+        print("enc. keys:  ", parse_enc(key_field_len))
+        print("swap size:  ", parse_size(hex(swap_size)))
+        print("swap_info:  ", parse_status(hex(swap_info)))
+        print("copy_done:  ", parse_status(hex(copy_done)))
+        print("image_ok:   ", parse_status(hex(image_ok)))
+        print("boot magic: ", parse_boot_magic(trailer_magic))
         print()
 
-    str1 = "#### End of Image "
-    str2 = "#" * (_LINE_LENGTH - len(str1))
-    print(str1 + str2)
+    footer = "End of Image "
+    print_in_row(footer)