scripts: dts: extract pickled EDT generation

Separate the pickled EDT generation from the C-Macro header
generation in gen_defines.py to have a more clear responsibility
of the scripts in the DTS parsing process.

Signed-off-by: Benedikt Schmidt <benedikt.schmidt@embedded-solutions.at>
diff --git a/scripts/dts/gen_defines.py b/scripts/dts/gen_defines.py
index f049f7b..fda6152 100755
--- a/scripts/dts/gen_defines.py
+++ b/scripts/dts/gen_defines.py
@@ -2,16 +2,11 @@
 
 # Copyright (c) 2019 - 2020 Nordic Semiconductor ASA
 # Copyright (c) 2019 Linaro Limited
+# Copyright (c) 2024 SILA Embedded Solutions GmbH
 # SPDX-License-Identifier: BSD-3-Clause
 
-# This script uses edtlib to generate a header file from a devicetree
-# (.dts) file. Information from binding files in YAML format is used
-# as well.
-#
-# Bindings are files that describe devicetree nodes. Devicetree nodes are
-# usually mapped to bindings via their 'compatible = "..."' property.
-#
-# See Zephyr's Devicetree user guide for details.
+# This script uses edtlib to generate a header file from a pickled
+# edt file.
 #
 # Note: Do not access private (_-prefixed) identifiers from edtlib here (and
 # also note that edtlib is not meant to expose the dtlib API directly).
@@ -20,7 +15,6 @@
 
 import argparse
 from collections import defaultdict
-import logging
 import os
 import pathlib
 import pickle
@@ -31,18 +25,9 @@
 sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'python-devicetree',
                                 'src'))
 
+import edtlib_logger
 from devicetree import edtlib
 
-class LogFormatter(logging.Formatter):
-    '''A log formatter that prints the level name in lower case,
-    for compatibility with earlier versions of edtlib.'''
-
-    def __init__(self):
-        super().__init__(fmt='%(levelnamelower)s: %(message)s')
-
-    def format(self, record):
-        record.levelnamelower = record.levelname.lower()
-        return super().format(record)
 
 def main():
     global header_file
@@ -50,30 +35,13 @@
 
     args = parse_args()
 
-    setup_edtlib_logging()
+    edtlib_logger.setup_edtlib_logging()
 
-    vendor_prefixes = {}
-    for prefixes_file in args.vendor_prefixes:
-        vendor_prefixes.update(edtlib.load_vendor_prefixes_txt(prefixes_file))
-
-    try:
-        edt = edtlib.EDT(args.dts, args.bindings_dirs,
-                         # Suppress this warning if it's suppressed in dtc
-                         warn_reg_unit_address_mismatch=
-                             "-Wno-simple_bus_reg" not in args.dtc_flags,
-                         default_prop_types=True,
-                         infer_binding_for_paths=["/zephyr,user"],
-                         werror=args.edtlib_Werror,
-                         vendor_prefixes=vendor_prefixes)
-    except edtlib.EDTError as e:
-        sys.exit(f"devicetree error: {e}")
+    with open(args.edt_pickle, 'rb') as f:
+        edt = pickle.load(f)
 
     flash_area_num = 0
 
-    # Save merged DTS source, as a debugging aid
-    with open(args.dts_out, "w", encoding="utf-8") as f:
-        print(edt.dts_source, file=f)
-
     # Create the generated header.
     with open(args.header_out, "w", encoding="utf-8") as header_file:
         write_top_comment(edt)
@@ -133,22 +101,6 @@
         write_chosen(edt)
         write_global_macros(edt)
 
-    if args.edt_pickle_out:
-        write_pickled_edt(edt, args.edt_pickle_out)
-
-
-def setup_edtlib_logging() -> None:
-    # The edtlib module emits logs using the standard 'logging' module.
-    # Configure it so that warnings and above are printed to stderr,
-    # using the LogFormatter class defined above to format each message.
-
-    handler = logging.StreamHandler(sys.stderr)
-    handler.setFormatter(LogFormatter())
-
-    logger = logging.getLogger('edtlib')
-    logger.setLevel(logging.WARNING)
-    logger.addHandler(handler)
-
 
 def node_z_path_id(node: edtlib.Node) -> str:
     # Return the node specific bit of the node's path identifier:
@@ -173,27 +125,10 @@
     # Returns parsed command-line arguments
 
     parser = argparse.ArgumentParser(allow_abbrev=False)
-    parser.add_argument("--dts", required=True, help="DTS file")
-    parser.add_argument("--dtc-flags",
-                        help="'dtc' devicetree compiler flags, some of which "
-                             "might be respected here")
-    parser.add_argument("--bindings-dirs", nargs='+', required=True,
-                        help="directory with bindings in YAML format, "
-                        "we allow multiple")
     parser.add_argument("--header-out", required=True,
                         help="path to write header to")
-    parser.add_argument("--dts-out", required=True,
-                        help="path to write merged DTS source code to (e.g. "
-                             "as a debugging aid)")
-    parser.add_argument("--edt-pickle-out",
-                        help="path to write pickled edtlib.EDT object to")
-    parser.add_argument("--vendor-prefixes", action='append', default=[],
-                        help="vendor-prefixes.txt path; used for validation; "
-                             "may be given multiple times")
-    parser.add_argument("--edtlib-Werror", action="store_true",
-                        help="if set, edtlib-specific warnings become errors. "
-                             "(this does not apply to warnings shared "
-                             "with dtc.)")
+    parser.add_argument("--edt-pickle",
+                        help="path to read pickled edtlib.EDT object from")
 
     return parser.parse_args()
 
@@ -1099,21 +1034,6 @@
     return f'"{escape(s)}"'
 
 
-def write_pickled_edt(edt: edtlib.EDT, out_file: str) -> None:
-    # Writes the edt object in pickle format to out_file.
-
-    with open(out_file, 'wb') as f:
-        # Pickle protocol version 4 is the default as of Python 3.8
-        # and was introduced in 3.4, so it is both available and
-        # recommended on all versions of Python that Zephyr supports
-        # (at time of writing, Python 3.6 was Zephyr's minimum
-        # version, and 3.8 the most recent CPython release).
-        #
-        # Using a common protocol version here will hopefully avoid
-        # reproducibility issues in different Python installations.
-        pickle.dump(edt, f, protocol=4)
-
-
 def err(s: str) -> NoReturn:
     raise Exception(s)