1#!/usr/bin/env python
2#
3# SPDX-FileCopyrightText: 2014-2022 Fredrik Ahlberg, Angus Gratton,
4# Espressif Systems (Shanghai) CO LTD, other contributors as noted.
5#
6# SPDX-License-Identifier: GPL-2.0-or-later
7
8import os
9import sys
10
11import esptool
12
13# Compare the esptool stub loaders to freshly built ones in the build directory
14#
15# (Used by CI to verify the stubs are up to date.)
16
17THIS_SCRIPT_DIR = os.path.dirname(__file__)
18STUB_DIR = "../esptool/targets/stub_flasher/"
19BUILD_DIR = "build/"
20JSON_NAME = "stub_flasher_{}.json"
21
22
23def diff(path_to_new, path_to_old):
24    output = ""
25    new = esptool.loader.StubFlasher(path_to_new)
26    old = esptool.loader.StubFlasher(path_to_old)
27
28    if new.data_start != old.data_start:
29        output += "  Data start: New {:#x}, old {:#x} \n".format(
30            new.data_start, old.data_start
31        )
32    if new.text_start != old.text_start:
33        output += "  Text start: New {:#x}, old {:#x} \n".format(
34            new.text_start, old.text_start
35        )
36    if new.entry != old.entry:
37        output += "  Entrypoint: New {:#x}, old {:#x} \n".format(new.entry, old.entry)
38
39    # data
40    if new.data != old.data:
41        if len(new.data) == len(old.data):
42            for i, (new_b, old_b) in enumerate(zip(new.data, old.data)):
43                if new_b != old_b:
44                    output += "  Data byte {:#x}: new {:#04x} old {:#04x} \n".format(
45                        i, new_b, old_b
46                    )
47        else:
48            output += "  Data length: New {} bytes, old {} bytes \n".format(
49                len(new.data), len(old.data)
50            )
51
52    # text
53    if new.text != old.text:
54        if len(new.text) == len(old.text):
55            for i, (new_b, old_b) in enumerate(zip(new.text, old.text)):
56                if new_b != old_b:
57                    output += "  Text byte {:#x}: new {:#04x} old {:#04x} \n".format(
58                        i, new_b, old_b
59                    )
60        else:
61            output += "  Text length: New {} bytes, old {} bytes \n".format(
62                len(new.text), len(old.text)
63            )
64    return output
65
66
67if __name__ == "__main__":
68    same = True
69    for chip in esptool.CHIP_LIST:
70        print("Comparing {} stub: ".format(chip), end="")
71        # TODO: [ESP32C5] ESPTOOL-825 remove when supported stub flasher
72        # TODO: [ESP32C61] IDF-9241 remove when supported stub flasher
73        if chip in ["esp32c5", "esp32c61"]:
74            print(f"{chip} has not supported stub yet, skipping...")
75            continue
76
77        chip = chip.replace("esp", "")
78        old = os.path.join(THIS_SCRIPT_DIR, STUB_DIR, JSON_NAME.format(chip))
79        new = os.path.join(THIS_SCRIPT_DIR, BUILD_DIR, JSON_NAME.format(chip))
80
81        output = diff(new, old)
82        if output != "":
83            same = False
84            print("FAIL")
85            print(
86                "  Mismatch: {} json file in esptool/targets/stub_flasher/ differs "
87                "from the just-built stub".format("esp" + chip)
88            )
89            print(output)
90        else:
91            print("OK")
92
93    if not same:
94        sys.exit(1)
95    else:
96        print("Stub flasher json files are the same")
97        sys.exit(0)
98