Skip to content

merge: support 'identical' on overlapped data #44

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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')

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The test in itself looks legit, but the test_merge_wrong_args right above this one now yields an incomplete message if triggered. Please add the new argument into that message and make it work again.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hum, seems that I didn't play the test... Any it's fixed.

I also updated the docs/

def test_merge_start_addr(self):
# this, None
Expand Down