Skip to content

Commit

Permalink
merge: support 'identical' on overlapped data
Browse files Browse the repository at this point in the history
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
  • Loading branch information
MarcFinetRtone committed Jul 1, 2021
1 parent 2fd8f41 commit 5e2b05b
Show file tree
Hide file tree
Showing 5 changed files with 26 additions and 5 deletions.
1 change: 1 addition & 0 deletions docs/manual/part2-6.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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::

Expand Down
2 changes: 2 additions & 0 deletions docs/manual/part3-4.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 8 additions & 3 deletions intelhex/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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:
Expand Down
4 changes: 3 additions & 1 deletion intelhex/scripts/hexmerge.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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')
Expand Down
13 changes: 12 additions & 1 deletion intelhex/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand All @@ -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
Expand Down

0 comments on commit 5e2b05b

Please sign in to comment.