From 5e2b05b219b34f8792a322b6ef029c6b1f42dbb9 Mon Sep 17 00:00:00 2001 From: Marc Finet Date: Wed, 18 Mar 2020 10:32:00 +0100 Subject: [PATCH] merge: support 'identical' on overlapped data When merging multiple .hex files, in case of overlap we sometimes need to just 'ensure' that values are identical. The new 'identical' mode ensures this. Note: the behavior for start_addr is currently a 'identical' (i.e. the overlap configuration is checked only when values differ). So we might want to change the behavior for data too: - if data is identical: silently bail out - add a 'stricter' mode that corresponds to the current behavior --- docs/manual/part2-6.txt | 1 + docs/manual/part3-4.txt | 2 ++ intelhex/__init__.py | 11 ++++++++--- intelhex/scripts/hexmerge.py | 4 +++- intelhex/test.py | 13 ++++++++++++- 5 files changed, 26 insertions(+), 5 deletions(-) diff --git a/docs/manual/part2-6.txt b/docs/manual/part2-6.txt index 7a44943..62dcf64 100644 --- a/docs/manual/part2-6.txt +++ b/docs/manual/part2-6.txt @@ -16,6 +16,7 @@ It can take three options: * ``error`` - stop and raise an exception (default) * ``ignore`` - keep data from the original that contains data at overlapped address * ``replace`` - use data from the new object that contains data at overlapped address +* ``identical`` - raise an exception if data is different You can merge only part of other hex file by using slice index notation:: diff --git a/docs/manual/part3-4.txt b/docs/manual/part3-4.txt index 7b5b8b8..2205261 100644 --- a/docs/manual/part3-4.txt +++ b/docs/manual/part3-4.txt @@ -22,6 +22,8 @@ This is a script to merge two different hex files. It is a frontend for the contains data at overlapped address * replace -- use data from last file that contains data at overlapped address + * identical -- raise error if data differ + Arguments: FILES list of hex files for merging diff --git a/intelhex/__init__.py b/intelhex/__init__.py index 091b5ab..c96998a 100644 --- a/intelhex/__init__.py +++ b/intelhex/__init__.py @@ -853,7 +853,9 @@ def merge(self, other, overlap='error'): - ignore: ignore other data and keep current data in overlapping region; - replace: replace data with other data - in overlapping region. + in overlapping region; + - identical: raising OverlapError if data is not + identical. @raise TypeError if other is not instance of IntelHex @raise ValueError if other is the same object as self @@ -866,9 +868,9 @@ def merge(self, other, overlap='error'): raise TypeError('other should be IntelHex object') if other is self: raise ValueError("Can't merge itself") - if overlap not in ('error', 'ignore', 'replace'): + if overlap not in ('error', 'ignore', 'replace', 'identical'): raise ValueError("overlap argument should be either " - "'error', 'ignore' or 'replace'") + "'error', 'ignore', 'replace' or 'identical'") # merge data this_buf = self._buf other_buf = other._buf @@ -879,6 +881,9 @@ def merge(self, other, overlap='error'): 'Data overlapped at address 0x%X' % i) elif overlap == 'ignore': continue + elif overlap == 'identical' and this_buf[i] != other_buf[i]: + raise AddressOverlapError( + 'Data at address 0x%X is different: 0x%X vs. 0x%X' % (i, this_buf[i], other_buf[i])) this_buf[i] = other_buf[i] # merge start_addr if self.start_addr != other.start_addr: diff --git a/intelhex/scripts/hexmerge.py b/intelhex/scripts/hexmerge.py index 8be98e8..350b55f 100755 --- a/intelhex/scripts/hexmerge.py +++ b/intelhex/scripts/hexmerge.py @@ -57,6 +57,8 @@ contains data at overlapped address * replace -- use data from last file that contains data at overlapped address + * identical -- if overlapped data verifies that values + are identical Arguments: FILES list of hex files for merging @@ -122,7 +124,7 @@ def main(args=None): elif o == '--no-start-addr': write_start_addr = False elif o == '--overlap': - if a in ('error', 'ignore', 'replace'): + if a in ('error', 'ignore', 'replace', 'identical'): overlap = a else: raise getopt.GetoptError('Bad overlap value') diff --git a/intelhex/test.py b/intelhex/test.py index df89276..90bd694 100755 --- a/intelhex/test.py +++ b/intelhex/test.py @@ -1171,7 +1171,7 @@ def test_merge_wrong_args(self): ih1.merge, ih1) ih2 = IntelHex() self.assertRaisesMsg(ValueError, "overlap argument should be either " - "'error', 'ignore' or 'replace'", + "'error', 'ignore', 'replace' or 'identical'", ih1.merge, ih2, overlap='spam') def test_merge_overlap(self): @@ -1191,6 +1191,17 @@ def test_merge_overlap(self): ih2 = IntelHex({0:2}) ih1.merge(ih2, overlap='replace') self.assertEqual({0:2}, ih1.todict()) + # identical: same value: ok + ih1 = IntelHex({0:1}) + ih2 = IntelHex({0:1}) + ih1.merge(ih2, overlap='identical') + self.assertEqual({0:1}, ih1.todict()) + # identical: different value: raise error + ih1 = IntelHex({0:1}) + ih2 = IntelHex({0:2}) + self.assertRaisesMsg(intelhex.AddressOverlapError, + 'Data at address 0x0 is different: 0x1 vs. 0x2', + ih1.merge, ih2, overlap='identical') def test_merge_start_addr(self): # this, None