objutils 0.10.2__tar.gz → 0.10.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {objutils-0.10.2 → objutils-0.10.3}/PKG-INFO +1 -1
- {objutils-0.10.2 → objutils-0.10.3}/objutils/__init__.py +1 -1
- {objutils-0.10.2 → objutils-0.10.3}/objutils/cosmac.py +7 -4
- {objutils-0.10.2 → objutils-0.10.3}/objutils/emon52.py +3 -1
- {objutils-0.10.2 → objutils-0.10.3}/objutils/etek.py +12 -6
- {objutils-0.10.2 → objutils-0.10.3}/objutils/hexfile.py +3 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/shf.py +1 -1
- {objutils-0.10.2 → objutils-0.10.3}/objutils/srec.py +2 -2
- objutils-0.10.3/objutils/tests/test_etek.py +161 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/version.py +1 -1
- {objutils-0.10.2 → objutils-0.10.3}/pyproject.toml +2 -2
- {objutils-0.10.2 → objutils-0.10.3}/CMakeLists.txt +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/LICENSE +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/build_ext.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/docs/README.rst +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/.coveragerc +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/.vscode/launch.json +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/.vscode/settings.json +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/a2l_test.shf +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/ash.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/binfile.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/checksums.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/.traverser.py.un~ +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/attrparser.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/c_generator.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/constants.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/encoding.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/lineprog.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/readers.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/sm.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/dwarf/traverser.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/elf/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/elf/arm/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/elf/arm/attributes.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/elf/defs.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/elf/model.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/exceptions.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/ctre.hpp +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/difflib.h +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/exceptions.cpp +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/exceptions.hpp +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/hexfile.cpp +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/extensions/wrapper.cpp +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/fpc.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/hexdump.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/ieee695.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/ihex.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/image.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/logger.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/mostec.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/objutils.code-workspace +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/pecoff/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/pecoff/defs.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/pecoff/model.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/pecoff/pdb/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/pickleif.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/rca.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/readers.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/registry.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/arduino_build_artifacts.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_cgen.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_coff_extract.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_coff_import.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_coff_info.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_coff_syms.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_dwarf_import.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_elf_arm_attrs.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_elf_extract.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_elf_import.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_elf_info.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_elf_syms.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/scripts/oj_hex_info.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/section.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/sig.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tek.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_arm_attributes.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_ash.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_c_generator.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_checksums.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_cygpath.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_diff_bin.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_elf.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_emon52.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_examples_cgen.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_fpc.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_hexdump.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_hexfile.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_ihex.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_image.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_mostec.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_readers.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_registry.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_repr.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_section.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_section_join.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_shf.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_sm.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_srec.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_tek.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/tests/test_titext.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/titxt.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/utils/__init__.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/utils/arduino.py +0 -0
- {objutils-0.10.2 → objutils-0.10.3}/objutils/utils/diff.py +0 -0
|
@@ -5,11 +5,14 @@ This module handles the RCA Cosmac hex format, used with RCA 1802/1804/1805
|
|
|
5
5
|
microprocessors and COSMAC development systems.
|
|
6
6
|
|
|
7
7
|
Format specification:
|
|
8
|
+
|
|
8
9
|
- Four data record formats with optional address:
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
10
|
+
|
|
11
|
+
1. ``!MAAAA DD`` – Full format with start symbol
|
|
12
|
+
2. ``?MAAAA DD`` – Alternate start symbol
|
|
13
|
+
3. ``AAAA DD`` – Address only (no symbol)
|
|
14
|
+
4. ``DD`` – Data only (address continues from previous)
|
|
15
|
+
|
|
13
16
|
- M: Memory identifier (single hex digit)
|
|
14
17
|
- AAAA: 16-bit address (hex)
|
|
15
18
|
- DD: Data bytes (hex, space-separated)
|
|
@@ -5,7 +5,9 @@ This module handles the EMON52 hex format used by the Elektor
|
|
|
5
5
|
Electronics EMON52 8052 development system.
|
|
6
6
|
|
|
7
7
|
Format specification:
|
|
8
|
-
|
|
8
|
+
|
|
9
|
+
- Data records: ``LL AAAA:DD CCCC``
|
|
10
|
+
|
|
9
11
|
- LL: Length/byte count (hex)
|
|
10
12
|
- AAAA: 16-bit address (hex)
|
|
11
13
|
- DD: Data bytes (hex, space-separated)
|
|
@@ -5,18 +5,24 @@ This module handles the Extended Tektronix hex format, an extension
|
|
|
5
5
|
of the standard Tektronix format with 24-bit addressing and symbol support.
|
|
6
6
|
|
|
7
7
|
Format specification:
|
|
8
|
-
|
|
9
|
-
|
|
8
|
+
|
|
9
|
+
- Data records: ``%LL6CCAAAAADD``
|
|
10
|
+
|
|
11
|
+
- LL: Length field (``2 * (data_length + 5)`` in hex)
|
|
10
12
|
- 6: Record type identifier
|
|
11
13
|
- CC: Checksum (nibble sum)
|
|
12
14
|
- AAAAAA: 24-bit address (hex)
|
|
13
15
|
- DD: Data bytes (hex)
|
|
14
|
-
|
|
16
|
+
|
|
17
|
+
- Symbol records: ``%LL3CCU``
|
|
18
|
+
|
|
15
19
|
- LL: Length field
|
|
16
20
|
- 3: Symbol type identifier
|
|
17
21
|
- CC: Checksum
|
|
18
22
|
- U: Symbol string (name + address)
|
|
19
|
-
|
|
23
|
+
|
|
24
|
+
- EOF records: ``%LL8CCAAAAADD``
|
|
25
|
+
|
|
20
26
|
- 8: EOF type identifier
|
|
21
27
|
"""
|
|
22
28
|
|
|
@@ -67,9 +73,9 @@ class Reader(hexfile.Reader):
|
|
|
67
73
|
VALID_CHARS = re.compile(r"^[a-zA-Z0-9_ %\n\r]*$")
|
|
68
74
|
|
|
69
75
|
FORMAT_SPEC = (
|
|
70
|
-
(DATA, "%
|
|
76
|
+
(DATA, "%LL6CCAAAAAADD"),
|
|
71
77
|
(SYMBOL, "%LL3CCU"),
|
|
72
|
-
(EOF, "%
|
|
78
|
+
(EOF, "%LL8CCAAAAAADD"),
|
|
73
79
|
)
|
|
74
80
|
|
|
75
81
|
def check_line(self, line: Any, format_type: int) -> None:
|
|
@@ -508,6 +508,7 @@ class Container:
|
|
|
508
508
|
length: Optional[int] = None
|
|
509
509
|
type: Optional[int] = None
|
|
510
510
|
checksum: Optional[int] = None
|
|
511
|
+
addrChecksum: Optional[int] = None
|
|
511
512
|
chunk: Optional[bytearray] = None
|
|
512
513
|
junk: Optional[str] = None
|
|
513
514
|
processing_instructions: list[Any] = field(default_factory=list)
|
|
@@ -892,6 +893,7 @@ class Reader(BaseType):
|
|
|
892
893
|
length = self._parse_optional_int(dict_, "length")
|
|
893
894
|
record_type = self._parse_optional_int(dict_, "type")
|
|
894
895
|
checksum = self._parse_optional_int(dict_, "checksum")
|
|
896
|
+
addr_checksum = self._parse_optional_int(dict_, "addrChecksum")
|
|
895
897
|
junk = dict_.get("junk")
|
|
896
898
|
|
|
897
899
|
# Parse data chunk
|
|
@@ -912,6 +914,7 @@ class Reader(BaseType):
|
|
|
912
914
|
length=length,
|
|
913
915
|
type=record_type,
|
|
914
916
|
checksum=checksum,
|
|
917
|
+
addrChecksum=addr_checksum,
|
|
915
918
|
chunk=chunk,
|
|
916
919
|
junk=junk,
|
|
917
920
|
)
|
|
@@ -30,7 +30,7 @@ from hashlib import sha1
|
|
|
30
30
|
|
|
31
31
|
from objutils.image import Image
|
|
32
32
|
from objutils.logger import Logger
|
|
33
|
-
from objutils.section import Section
|
|
33
|
+
from objutils.section import Section, join_sections
|
|
34
34
|
from objutils.utils import create_string_buffer
|
|
35
35
|
|
|
36
36
|
SHF_DTD = """<!--
|
|
@@ -151,14 +151,14 @@ class Reader(hexfile.Reader):
|
|
|
151
151
|
)
|
|
152
152
|
else:
|
|
153
153
|
raise TypeError(f"Invalid format type {format_type}.")
|
|
154
|
-
if hasattr(line, "chunk"):
|
|
154
|
+
if hasattr(line, "chunk") and line.chunk is not None:
|
|
155
155
|
checksum = (~(sum([line.length, checksum_of_address]) + sum(line.chunk))) & 0xFF
|
|
156
156
|
else:
|
|
157
157
|
checksum = (~(sum([line.length, checksum_of_address]))) & 0xFF
|
|
158
158
|
if line.checksum != checksum:
|
|
159
159
|
raise hexfile.InvalidRecordChecksumError()
|
|
160
160
|
line.length -= BIAS[format_type] # calculate actual data length.
|
|
161
|
-
if hasattr(line, "chunk") and line.length and (line.length != len(line.chunk)):
|
|
161
|
+
if hasattr(line, "chunk") and line.chunk is not None and line.length and (line.length != len(line.chunk)):
|
|
162
162
|
raise hexfile.InvalidRecordLengthError("Byte count doesn't match length of actual data.")
|
|
163
163
|
|
|
164
164
|
def is_data_line(self, line: Any, format_type: int) -> bool:
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
"""Tests for the Extended Tektronix (ETek) hex file format.
|
|
3
|
+
|
|
4
|
+
Coverage:
|
|
5
|
+
- loads(): parsing ETek → Image
|
|
6
|
+
- dumps(): serialising Image → ETek
|
|
7
|
+
- Roundtrip fidelity in both directions (ETek↔SREC)
|
|
8
|
+
- Single-byte records at extreme 24-bit addresses
|
|
9
|
+
- Checksum mismatch detection
|
|
10
|
+
- Record-length mismatch detection
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
import pytest
|
|
14
|
+
|
|
15
|
+
from objutils import dumps, loads
|
|
16
|
+
from objutils.hexfile import InvalidRecordChecksumError, InvalidRecordLengthError
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
# ---------------------------------------------------------------------------
|
|
20
|
+
# Test vectors
|
|
21
|
+
# ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
# 60-byte message split into three 16-byte and one 12-byte data record
|
|
24
|
+
# starting at address 0xB000 (24-bit addressing).
|
|
25
|
+
ETEK = (
|
|
26
|
+
b"%2A6C200B000576F77212044696420796F7520726561\n"
|
|
27
|
+
b"%2A6DF00B0106C6C7920676F207468726F7567682061\n"
|
|
28
|
+
b"%2A6CE00B0206C6C20746861742074726F75626C6520\n"
|
|
29
|
+
b"%246A700B030746F207265616420746869733F\n"
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
# Equivalent Motorola S-Record representation (used for cross-format checks).
|
|
33
|
+
S19 = (
|
|
34
|
+
b"S113B000576F77212044696420796F7520726561D8\n"
|
|
35
|
+
b"S113B0106C6C7920676F207468726F756768206143\n"
|
|
36
|
+
b"S113B0206C6C20746861742074726F75626C652036\n"
|
|
37
|
+
b"S110B030746F207265616420746869733F59\n"
|
|
38
|
+
b"S5030004F8\n"
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# Single-byte records for boundary / 24-bit address tests.
|
|
42
|
+
ETEK_SINGLE_BYTE_LOW = b"%0C628000001AB\n" # address 0x000001, data 0xAB
|
|
43
|
+
ETEK_SINGLE_BYTE_HIGH = b"%0C649FF0000CD\n" # address 0xFF0000, data 0xCD
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
# ---------------------------------------------------------------------------
|
|
47
|
+
# Helpers
|
|
48
|
+
# ---------------------------------------------------------------------------
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _etek_loads(raw: bytes):
|
|
52
|
+
"""Load an ETek byte string and return the Image."""
|
|
53
|
+
return loads("etek", raw)
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
def _srec_loads(raw: bytes):
|
|
57
|
+
"""Load an SREC byte string and return the Image."""
|
|
58
|
+
return loads("srec", raw)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
# ---------------------------------------------------------------------------
|
|
62
|
+
# loads() – parsing
|
|
63
|
+
# ---------------------------------------------------------------------------
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
def test_loads_produces_correct_srec_output():
|
|
67
|
+
"""Parsing ETek data produces byte-identical S-Record output."""
|
|
68
|
+
img = _etek_loads(ETEK)
|
|
69
|
+
assert dumps("srec", img, s5record=True) == S19
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
def test_loads_single_byte_low_address():
|
|
73
|
+
"""Single data byte at address 0x000001 is read correctly."""
|
|
74
|
+
img = _etek_loads(ETEK_SINGLE_BYTE_LOW)
|
|
75
|
+
assert img.read(0x000001, 1) == b"\xAB"
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
def test_loads_single_byte_high_address():
|
|
79
|
+
"""Single data byte at address 0xFF0000 (max 24-bit) is read correctly."""
|
|
80
|
+
img = _etek_loads(ETEK_SINGLE_BYTE_HIGH)
|
|
81
|
+
assert img.read(0xFF0000, 1) == b"\xCD"
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def test_loads_image_min_address():
|
|
85
|
+
"""Parsed image starts at the expected minimum address."""
|
|
86
|
+
img = _etek_loads(ETEK)
|
|
87
|
+
first_section = next(iter(img.sections))
|
|
88
|
+
assert first_section.start_address == 0xB000
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def test_loads_image_data_length():
|
|
92
|
+
"""Parsed image contains the correct number of data bytes (61 = 3×16 + 13)."""
|
|
93
|
+
img = _etek_loads(ETEK)
|
|
94
|
+
total = sum(len(s.data) for s in img.sections)
|
|
95
|
+
assert total == 61
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
# ---------------------------------------------------------------------------
|
|
99
|
+
# dumps() – serialisation
|
|
100
|
+
# ---------------------------------------------------------------------------
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_dumps_produces_correct_etek_output():
|
|
104
|
+
"""Serialising an Image loaded from S-Records gives identical ETek bytes."""
|
|
105
|
+
img = _srec_loads(S19)
|
|
106
|
+
assert dumps("etek", img) == bytearray(ETEK)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def test_dumps_single_byte_low_address():
|
|
110
|
+
"""A one-byte section at address 0x000001 serialises to the expected record."""
|
|
111
|
+
img = _etek_loads(ETEK_SINGLE_BYTE_LOW)
|
|
112
|
+
assert dumps("etek", img) == bytearray(ETEK_SINGLE_BYTE_LOW)
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
def test_dumps_single_byte_high_address():
|
|
116
|
+
"""A one-byte section at address 0xFF0000 serialises to the expected record."""
|
|
117
|
+
img = _etek_loads(ETEK_SINGLE_BYTE_HIGH)
|
|
118
|
+
assert dumps("etek", img) == bytearray(ETEK_SINGLE_BYTE_HIGH)
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
# ---------------------------------------------------------------------------
|
|
122
|
+
# Roundtrip tests
|
|
123
|
+
# ---------------------------------------------------------------------------
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def test_roundtrip_etek_to_srec_to_etek():
|
|
127
|
+
"""ETek → SREC → ETek roundtrip preserves all data and addresses."""
|
|
128
|
+
img1 = _etek_loads(ETEK)
|
|
129
|
+
srec_data = dumps("srec", img1, s5record=True)
|
|
130
|
+
img2 = _srec_loads(srec_data)
|
|
131
|
+
assert dumps("etek", img2) == bytearray(ETEK)
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def test_roundtrip_srec_to_etek_to_srec():
|
|
135
|
+
"""SREC → ETek → SREC roundtrip preserves all data and addresses."""
|
|
136
|
+
img1 = _srec_loads(S19)
|
|
137
|
+
etek_data = dumps("etek", img1)
|
|
138
|
+
img2 = _etek_loads(etek_data)
|
|
139
|
+
assert dumps("srec", img2, s5record=True) == S19
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
# ---------------------------------------------------------------------------
|
|
143
|
+
# Error handling
|
|
144
|
+
# ---------------------------------------------------------------------------
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def test_invalid_checksum_raises():
|
|
148
|
+
"""A record with a corrupted checksum raises InvalidRecordChecksumError."""
|
|
149
|
+
# Flip one nibble in the CC field (chars 4-5 of the record).
|
|
150
|
+
bad = b"%2A6FF00B000576F77212044696420796F7520726561\n"
|
|
151
|
+
with pytest.raises(InvalidRecordChecksumError):
|
|
152
|
+
_etek_loads(bad)
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def test_invalid_length_raises():
|
|
156
|
+
"""A record with a wrong LL field raises InvalidRecordLengthError."""
|
|
157
|
+
# Change LL from 2A to 2C (claims 19 data bytes but only 16 are present).
|
|
158
|
+
bad = b"%2C6C200B000576F77212044696420796F7520726561\n"
|
|
159
|
+
with pytest.raises(InvalidRecordLengthError):
|
|
160
|
+
_etek_loads(bad)
|
|
161
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "objutils"
|
|
3
|
-
version = "0.10.
|
|
3
|
+
version = "0.10.3"
|
|
4
4
|
description = "Objectfile library for Python"
|
|
5
5
|
authors = ["Christoph Schueler <cpu12.gems@googlemail.com>"]
|
|
6
6
|
license = "GPLv2"
|
|
@@ -121,7 +121,7 @@ skip = ["*_i686", "*-musllinux*"]
|
|
|
121
121
|
build-frontend = "build"
|
|
122
122
|
|
|
123
123
|
[tool.bumpver]
|
|
124
|
-
current_version = "0.10.
|
|
124
|
+
current_version = "0.10.3"
|
|
125
125
|
version_pattern = "MAJOR.MINOR.PATCH"
|
|
126
126
|
commit_message = "bump version {old_version} -> {new_version}"
|
|
127
127
|
commit = true
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|