objutils 0.10.11__tar.gz → 0.10.13__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.
Files changed (274) hide show
  1. {objutils-0.10.11 → objutils-0.10.13}/.pre-commit-config.yaml +1 -1
  2. {objutils-0.10.11 → objutils-0.10.13}/PKG-INFO +15 -2
  3. {objutils-0.10.11 → objutils-0.10.13}/docs/README.rst +11 -0
  4. {objutils-0.10.11 → objutils-0.10.13}/docs/scripts.rst +79 -9
  5. {objutils-0.10.11 → objutils-0.10.13}/objutils/__init__.py +1 -1
  6. {objutils-0.10.11 → objutils-0.10.13}/objutils/image.py +74 -20
  7. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_hex_info.py +1 -1
  8. objutils-0.10.13/objutils/scripts/oj_hex_merge.py +130 -0
  9. objutils-0.10.13/objutils/scripts/oj_hex_split.py +138 -0
  10. {objutils-0.10.11 → objutils-0.10.13}/objutils/section.py +28 -0
  11. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_image.py +37 -0
  12. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_section.py +18 -0
  13. {objutils-0.10.11 → objutils-0.10.13}/objutils/version.py +1 -1
  14. {objutils-0.10.11 → objutils-0.10.13}/poetry.lock +35 -23
  15. {objutils-0.10.11 → objutils-0.10.13}/pyproject.toml +9 -5
  16. objutils-0.10.11/.idea/objutils@1.iml +0 -11
  17. {objutils-0.10.11 → objutils-0.10.13}/.clang-format +0 -0
  18. {objutils-0.10.11 → objutils-0.10.13}/.codacy.yml +0 -0
  19. {objutils-0.10.11 → objutils-0.10.13}/.codeclimate.yml +0 -0
  20. {objutils-0.10.11 → objutils-0.10.13}/.coveralls.yml +0 -0
  21. {objutils-0.10.11 → objutils-0.10.13}/.github/FUNDING.yml +0 -0
  22. {objutils-0.10.11 → objutils-0.10.13}/.github/ISSUE_TEMPLATE/bug_report.yml +0 -0
  23. {objutils-0.10.11 → objutils-0.10.13}/.github/ISSUE_TEMPLATE/config.yml +0 -0
  24. {objutils-0.10.11 → objutils-0.10.13}/.github/ISSUE_TEMPLATE/documentation.yml +0 -0
  25. {objutils-0.10.11 → objutils-0.10.13}/.github/ISSUE_TEMPLATE/feature_request.yml +0 -0
  26. {objutils-0.10.11 → objutils-0.10.13}/.github/ISSUE_TEMPLATE.md +0 -0
  27. {objutils-0.10.11 → objutils-0.10.13}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  28. {objutils-0.10.11 → objutils-0.10.13}/.github/copilot-instructions.md +0 -0
  29. {objutils-0.10.11 → objutils-0.10.13}/.github/workflows/pythonapp.yml +0 -0
  30. {objutils-0.10.11 → objutils-0.10.13}/.gitignore +0 -0
  31. {objutils-0.10.11 → objutils-0.10.13}/.idea/.gitignore +0 -0
  32. {objutils-0.10.11 → objutils-0.10.13}/.idea/copilot.data.migration.ask2agent.xml +0 -0
  33. {objutils-0.10.11 → objutils-0.10.13}/.idea/deployment.xml +0 -0
  34. {objutils-0.10.11 → objutils-0.10.13}/.idea/inspectionProfiles/profiles_settings.xml +0 -0
  35. {objutils-0.10.11 → objutils-0.10.13}/.idea/misc.xml +0 -0
  36. {objutils-0.10.11 → objutils-0.10.13}/.idea/modules.xml +0 -0
  37. {objutils-0.10.11 → objutils-0.10.13}/.idea/pyLspTools.xml +0 -0
  38. {objutils-0.10.11 → objutils-0.10.13}/.idea/pyProjectModel.xml +0 -0
  39. {objutils-0.10.11 → objutils-0.10.13}/.idea/vcs.xml +0 -0
  40. {objutils-0.10.11 → objutils-0.10.13}/.pylintrc +0 -0
  41. {objutils-0.10.11 → objutils-0.10.13}/.readthedocs.yml +0 -0
  42. {objutils-0.10.11 → objutils-0.10.13}/.travis.yml +0 -0
  43. {objutils-0.10.11 → objutils-0.10.13}/CMakeLists.txt +0 -0
  44. {objutils-0.10.11 → objutils-0.10.13}/CODE_OF_CONDUCT.md +0 -0
  45. {objutils-0.10.11 → objutils-0.10.13}/CONTRIBUTORS +0 -0
  46. {objutils-0.10.11 → objutils-0.10.13}/LICENSE +0 -0
  47. {objutils-0.10.11 → objutils-0.10.13}/MANIFEST.in +0 -0
  48. {objutils-0.10.11 → objutils-0.10.13}/PULL_REQUEST_TEMPLATE.md +0 -0
  49. {objutils-0.10.11 → objutils-0.10.13}/appveyor.yml +0 -0
  50. {objutils-0.10.11 → objutils-0.10.13}/bandit.yml +0 -0
  51. {objutils-0.10.11 → objutils-0.10.13}/docs/Data_Formats.pdf +0 -0
  52. {objutils-0.10.11 → objutils-0.10.13}/docs/ELF_Format.pdf +0 -0
  53. {objutils-0.10.11 → objutils-0.10.13}/docs/KNOWN_GOOD_DWARF_REFERENCE.md +0 -0
  54. {objutils-0.10.11 → objutils-0.10.13}/docs/apidoc.sh +0 -0
  55. {objutils-0.10.11 → objutils-0.10.13}/docs/conf.py +0 -0
  56. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.buildinfo +0 -0
  57. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.buildinfo.bak +0 -0
  58. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/README.doctree +0 -0
  59. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/environment.pickle +0 -0
  60. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/howto.doctree +0 -0
  61. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/index.doctree +0 -0
  62. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/installation.doctree +0 -0
  63. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/modules.doctree +0 -0
  64. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/objutils.doctree +0 -0
  65. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/objutils.elf.doctree +0 -0
  66. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/scripts.doctree +0 -0
  67. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/session.doctree +0 -0
  68. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/.doctrees/tutorial.doctree +0 -0
  69. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/README.html +0 -0
  70. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_images/objutils_basic.png +0 -0
  71. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/index.html +0 -0
  72. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/ash.html +0 -0
  73. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/binfile.html +0 -0
  74. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/checksums.html +0 -0
  75. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/cosmac.html +0 -0
  76. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/elf/defs.html +0 -0
  77. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/elf.html +0 -0
  78. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/emon52.html +0 -0
  79. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/etek.html +0 -0
  80. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/exceptions.html +0 -0
  81. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/fpc.html +0 -0
  82. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/hexdump.html +0 -0
  83. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/hexfile.html +0 -0
  84. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/ihex.html +0 -0
  85. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/image.html +0 -0
  86. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/logger.html +0 -0
  87. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/mostec.html +0 -0
  88. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/pickleif.html +0 -0
  89. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/rca.html +0 -0
  90. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/readers.html +0 -0
  91. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/registry.html +0 -0
  92. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/section.html +0 -0
  93. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/sig.html +0 -0
  94. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/srec.html +0 -0
  95. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/tek.html +0 -0
  96. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/titxt.html +0 -0
  97. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils/utils.html +0 -0
  98. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_modules/objutils.html +0 -0
  99. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/README.rst.txt +0 -0
  100. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/howto.rst.txt +0 -0
  101. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/index.rst.txt +0 -0
  102. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/installation.rst.txt +0 -0
  103. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/modules.rst.txt +0 -0
  104. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/objutils.elf.rst.txt +0 -0
  105. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/objutils.rst.txt +0 -0
  106. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/scripts.rst.txt +0 -0
  107. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/session.rst.txt +0 -0
  108. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_sources/tutorial.rst.txt +0 -0
  109. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/alabaster.css +0 -0
  110. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/basic.css +0 -0
  111. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/check-solid.svg +0 -0
  112. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/clipboard.min.js +0 -0
  113. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/copy-button.svg +0 -0
  114. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/copybutton.css +0 -0
  115. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/copybutton.js +0 -0
  116. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/copybutton_funcs.js +0 -0
  117. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/custom.css +0 -0
  118. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/doctools.js +0 -0
  119. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/documentation_options.js +0 -0
  120. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/file.png +0 -0
  121. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/github-banner.svg +0 -0
  122. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/language_data.js +0 -0
  123. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/minus.png +0 -0
  124. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/plus.png +0 -0
  125. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/pygments.css +0 -0
  126. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/scripts/bootstrap.js +0 -0
  127. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/scripts/bootstrap.js.LICENSE.txt +0 -0
  128. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/scripts/fontawesome.js +0 -0
  129. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/scripts/fontawesome.js.LICENSE.txt +0 -0
  130. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/scripts/pydata-sphinx-theme.js +0 -0
  131. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/searchtools.js +0 -0
  132. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/sphinx_highlight.js +0 -0
  133. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/styles/pydata-sphinx-theme.css +0 -0
  134. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/styles/theme.css +0 -0
  135. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-brands-400.ttf +0 -0
  136. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-brands-400.woff2 +0 -0
  137. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-regular-400.ttf +0 -0
  138. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-regular-400.woff2 +0 -0
  139. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-solid-900.ttf +0 -0
  140. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/vendor/fontawesome/webfonts/fa-solid-900.woff2 +0 -0
  141. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/_static/webpack-macros.html +0 -0
  142. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/genindex.html +0 -0
  143. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/howto.html +0 -0
  144. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/index.html +0 -0
  145. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/installation.html +0 -0
  146. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/modules.html +0 -0
  147. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/objects.inv +0 -0
  148. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/objutils.elf.html +0 -0
  149. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/objutils.html +0 -0
  150. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/py-modindex.html +0 -0
  151. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/scripts.html +0 -0
  152. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/search.html +0 -0
  153. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/searchindex.js +0 -0
  154. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/session.html +0 -0
  155. {objutils-0.10.11 → objutils-0.10.13}/docs/docs/_build/html/tutorial.html +0 -0
  156. {objutils-0.10.11 → objutils-0.10.13}/docs/elf-64-gen.pdf +0 -0
  157. {objutils-0.10.11 → objutils-0.10.13}/docs/example0.srec +0 -0
  158. {objutils-0.10.11 → objutils-0.10.13}/docs/howto.rst +0 -0
  159. {objutils-0.10.11 → objutils-0.10.13}/docs/index.rst +0 -0
  160. {objutils-0.10.11 → objutils-0.10.13}/docs/installation.rst +0 -0
  161. {objutils-0.10.11 → objutils-0.10.13}/docs/make.bat +0 -0
  162. {objutils-0.10.11 → objutils-0.10.13}/docs/modules.rst +0 -0
  163. {objutils-0.10.11 → objutils-0.10.13}/docs/objutils.elf.rst +0 -0
  164. {objutils-0.10.11 → objutils-0.10.13}/docs/objutils.rst +0 -0
  165. {objutils-0.10.11 → objutils-0.10.13}/docs/objutils_banner.png +0 -0
  166. {objutils-0.10.11 → objutils-0.10.13}/docs/objutils_basic.png +0 -0
  167. {objutils-0.10.11 → objutils-0.10.13}/docs/objutils_dark.jpg +0 -0
  168. {objutils-0.10.11 → objutils-0.10.13}/docs/objutils_social.jpg +0 -0
  169. {objutils-0.10.11 → objutils-0.10.13}/docs/requirements.txt +0 -0
  170. {objutils-0.10.11 → objutils-0.10.13}/docs/session.rst +0 -0
  171. {objutils-0.10.11 → objutils-0.10.13}/docs/tutorial.rst +0 -0
  172. {objutils-0.10.11 → objutils-0.10.13}/docs/tutorial1.ipynb +0 -0
  173. {objutils-0.10.11 → objutils-0.10.13}/objutils/.coveragerc +0 -0
  174. {objutils-0.10.11 → objutils-0.10.13}/objutils/.vscode/launch.json +0 -0
  175. {objutils-0.10.11 → objutils-0.10.13}/objutils/.vscode/settings.json +0 -0
  176. {objutils-0.10.11 → objutils-0.10.13}/objutils/a2l_test.shf +0 -0
  177. {objutils-0.10.11 → objutils-0.10.13}/objutils/ash.py +0 -0
  178. {objutils-0.10.11 → objutils-0.10.13}/objutils/binfile.py +0 -0
  179. {objutils-0.10.11 → objutils-0.10.13}/objutils/checksums.py +0 -0
  180. {objutils-0.10.11 → objutils-0.10.13}/objutils/cosmac.py +0 -0
  181. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/__init__.py +0 -0
  182. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/attrparser.py +0 -0
  183. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/c_generator.py +0 -0
  184. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/constants.py +0 -0
  185. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/encoding.py +0 -0
  186. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/lineprog.py +0 -0
  187. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/readers.py +0 -0
  188. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/sm.py +0 -0
  189. {objutils-0.10.11 → objutils-0.10.13}/objutils/dwarf/traverser.py +0 -0
  190. {objutils-0.10.11 → objutils-0.10.13}/objutils/elf/__init__.py +0 -0
  191. {objutils-0.10.11 → objutils-0.10.13}/objutils/elf/arm/__init__.py +0 -0
  192. {objutils-0.10.11 → objutils-0.10.13}/objutils/elf/arm/attributes.py +0 -0
  193. {objutils-0.10.11 → objutils-0.10.13}/objutils/elf/defs.py +0 -0
  194. {objutils-0.10.11 → objutils-0.10.13}/objutils/elf/model.py +0 -0
  195. {objutils-0.10.11 → objutils-0.10.13}/objutils/emon52.py +0 -0
  196. {objutils-0.10.11 → objutils-0.10.13}/objutils/etek.py +0 -0
  197. {objutils-0.10.11 → objutils-0.10.13}/objutils/exceptions.py +0 -0
  198. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/__init__.py +0 -0
  199. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/ctre.hpp +0 -0
  200. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/difflib.h +0 -0
  201. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/exceptions.cpp +0 -0
  202. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/exceptions.hpp +0 -0
  203. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/hexfile.cpp +0 -0
  204. {objutils-0.10.11 → objutils-0.10.13}/objutils/extensions/wrapper.cpp +0 -0
  205. {objutils-0.10.11 → objutils-0.10.13}/objutils/fpc.py +0 -0
  206. {objutils-0.10.11 → objutils-0.10.13}/objutils/hexdump.py +0 -0
  207. {objutils-0.10.11 → objutils-0.10.13}/objutils/hexfile.py +0 -0
  208. {objutils-0.10.11 → objutils-0.10.13}/objutils/ieee695.py +0 -0
  209. {objutils-0.10.11 → objutils-0.10.13}/objutils/ihex.py +0 -0
  210. {objutils-0.10.11 → objutils-0.10.13}/objutils/logger.py +0 -0
  211. {objutils-0.10.11 → objutils-0.10.13}/objutils/mostec.py +0 -0
  212. {objutils-0.10.11 → objutils-0.10.13}/objutils/objutils.code-workspace +0 -0
  213. {objutils-0.10.11 → objutils-0.10.13}/objutils/oocdtxt.py +0 -0
  214. {objutils-0.10.11 → objutils-0.10.13}/objutils/pecoff/__init__.py +0 -0
  215. {objutils-0.10.11 → objutils-0.10.13}/objutils/pecoff/defs.py +0 -0
  216. {objutils-0.10.11 → objutils-0.10.13}/objutils/pecoff/model.py +0 -0
  217. {objutils-0.10.11 → objutils-0.10.13}/objutils/pecoff/pdb/__init__.py +0 -0
  218. {objutils-0.10.11 → objutils-0.10.13}/objutils/pickleif.py +0 -0
  219. {objutils-0.10.11 → objutils-0.10.13}/objutils/rca.py +0 -0
  220. {objutils-0.10.11 → objutils-0.10.13}/objutils/readers.py +0 -0
  221. {objutils-0.10.11 → objutils-0.10.13}/objutils/registry.py +0 -0
  222. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/arduino_build_artifacts.py +0 -0
  223. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_cgen.py +0 -0
  224. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_coff_extract.py +0 -0
  225. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_coff_import.py +0 -0
  226. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_coff_info.py +0 -0
  227. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_coff_syms.py +0 -0
  228. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_dwarf_import.py +0 -0
  229. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_dwarf_info.py +0 -0
  230. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_elf_arm_attrs.py +0 -0
  231. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_elf_extract.py +0 -0
  232. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_elf_import.py +0 -0
  233. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_elf_info.py +0 -0
  234. {objutils-0.10.11 → objutils-0.10.13}/objutils/scripts/oj_elf_syms.py +0 -0
  235. {objutils-0.10.11 → objutils-0.10.13}/objutils/shf.py +0 -0
  236. {objutils-0.10.11 → objutils-0.10.13}/objutils/sig.py +0 -0
  237. {objutils-0.10.11 → objutils-0.10.13}/objutils/srec.py +0 -0
  238. {objutils-0.10.11 → objutils-0.10.13}/objutils/symbols.py +0 -0
  239. {objutils-0.10.11 → objutils-0.10.13}/objutils/tek.py +0 -0
  240. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/__init__.py +0 -0
  241. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_arm_attributes.py +0 -0
  242. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_ash.py +0 -0
  243. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_c_generator.py +0 -0
  244. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_checksums.py +0 -0
  245. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_cygpath.py +0 -0
  246. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_diff_bin.py +0 -0
  247. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_elf.py +0 -0
  248. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_emon52.py +0 -0
  249. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_etek.py +0 -0
  250. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_examples_cgen.py +0 -0
  251. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_fpc.py +0 -0
  252. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_hexdump.py +0 -0
  253. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_hexfile.py +0 -0
  254. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_ihex.py +0 -0
  255. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_mostec.py +0 -0
  256. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_oocdtxt.py +0 -0
  257. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_readers.py +0 -0
  258. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_registry.py +0 -0
  259. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_repr.py +0 -0
  260. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_section_join.py +0 -0
  261. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_shf.py +0 -0
  262. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_sm.py +0 -0
  263. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_srec.py +0 -0
  264. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_tek.py +0 -0
  265. {objutils-0.10.11 → objutils-0.10.13}/objutils/tests/test_titext.py +0 -0
  266. {objutils-0.10.11 → objutils-0.10.13}/objutils/titxt.py +0 -0
  267. {objutils-0.10.11 → objutils-0.10.13}/objutils/utils/__init__.py +0 -0
  268. {objutils-0.10.11 → objutils-0.10.13}/objutils/utils/arduino.py +0 -0
  269. {objutils-0.10.11 → objutils-0.10.13}/objutils/utils/diff.py +0 -0
  270. {objutils-0.10.11 → objutils-0.10.13}/requirements.txt +0 -0
  271. {objutils-0.10.11 → objutils-0.10.13}/setup.cfg +0 -0
  272. {objutils-0.10.11 → objutils-0.10.13}/setup.py +0 -0
  273. {objutils-0.10.11 → objutils-0.10.13}/test_join_sections.py +0 -0
  274. {objutils-0.10.11 → objutils-0.10.13}/test_requirements.txt +0 -0
@@ -42,7 +42,7 @@ repos:
42
42
  args: ["--line-length=132"]
43
43
 
44
44
  - repo: https://github.com/astral-sh/ruff-pre-commit
45
- rev: v0.15.20
45
+ rev: v0.15.21
46
46
  hooks:
47
47
  - id: ruff
48
48
  args: ["--fix", "--exit-non-zero-on-fix"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: objutils
3
- Version: 0.10.11
3
+ Version: 0.10.13
4
4
  Summary: Objectfile library for Python
5
5
  Keywords: hex files,intel hex,s19,srec,srecords,object files,map files,embedded,microcontroller,ECU,shf,rfc4194
6
6
  Author-Email: Christoph Schueler <cpu12.gems@googlemail.com>
@@ -10,11 +10,12 @@ Classifier: Intended Audience :: Developers
10
10
  Classifier: Topic :: Software Development
11
11
  Classifier: Topic :: Scientific/Engineering
12
12
  Classifier: License :: OSI Approved :: GNU General Public License v2 (GPLv2)
13
- Classifier: Programming Language :: Python :: 3.9
14
13
  Classifier: Programming Language :: Python :: 3.10
15
14
  Classifier: Programming Language :: Python :: 3.11
16
15
  Classifier: Programming Language :: Python :: 3.12
17
16
  Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Programming Language :: Python :: 3.15
18
19
  Project-URL: Repository, https://www.github.com/Christoph2/objutils
19
20
  Requires-Python: <4.0,>=3.10
20
21
  Requires-Dist: construct>=2.10.70
@@ -22,6 +23,7 @@ Requires-Dist: mako>=1.3.3
22
23
  Requires-Dist: sqlalchemy>=2.0.29
23
24
  Requires-Dist: rich>=14.2
24
25
  Requires-Dist: numpy>=2.2.5
26
+ Requires-Dist: ufilename<0.2.0,>=0.1.1
25
27
  Provides-Extra: dev
26
28
  Requires-Dist: bumpver>=2023.1129; extra == "dev"
27
29
  Requires-Dist: pre-commit>=3.7.0; extra == "dev"
@@ -78,11 +80,14 @@ Features
78
80
 
79
81
  - Read ELF files (including symbols) and extract loadable sections.
80
82
  - Inspect PE/COFF files and symbols (optional PDB support).
83
+ - Merge multiple HEX files into one (``oj-hex-merge``).
84
+ - Split HEX files into separate sections (``oj-hex-split``).
81
85
  - Typed access (scalars, arrays, strings) to binary data.
82
86
 
83
87
  Recent improvements
84
88
  -------------------
85
89
 
90
+ - New ``oj-hex-merge`` and ``oj-hex-split`` CLI tools for combining and partitioning HEX files.
86
91
  - New ``oj-dwarf-import`` CLI replaces ``dwarfer.py``/``cu_info.py`` for DWARF imports, CU listing, summaries, and attribute traversal.
87
92
  - Faster DWARF imports: batched ORM writes, quiet flag propagation, and safe DWARF expression evaluation keep large ELF files stable.
88
93
  - Exception handling and typing tightened across DWARF/ELF/PECOFF modules and public APIs to surface real errors without masking them.
@@ -215,6 +220,14 @@ And loaded again...
215
220
  Section(address = 0X00001000, length = 16, data = b'Hello HEX world!')
216
221
  Section(address = 0X00002000, length = 16, data = b'\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10')
217
222
 
223
+ Or split it into its sections...
224
+
225
+ .. code-block:: python
226
+
227
+ images = img1.split()
228
+ for i, img in enumerate(images):
229
+ dump("srec", f"part_{i}.srec", img)
230
+
218
231
  This leads to the conversion idiom.
219
232
 
220
233
  .. code-block:: python
@@ -44,11 +44,14 @@ Features
44
44
 
45
45
  - Read ELF files (including symbols) and extract loadable sections.
46
46
  - Inspect PE/COFF files and symbols (optional PDB support).
47
+ - Merge multiple HEX files into one (``oj-hex-merge``).
48
+ - Split HEX files into separate sections (``oj-hex-split``).
47
49
  - Typed access (scalars, arrays, strings) to binary data.
48
50
 
49
51
  Recent improvements
50
52
  -------------------
51
53
 
54
+ - New ``oj-hex-merge`` and ``oj-hex-split`` CLI tools for combining and partitioning HEX files.
52
55
  - New ``oj-dwarf-import`` CLI replaces ``dwarfer.py``/``cu_info.py`` for DWARF imports, CU listing, summaries, and attribute traversal.
53
56
  - Faster DWARF imports: batched ORM writes, quiet flag propagation, and safe DWARF expression evaluation keep large ELF files stable.
54
57
  - Exception handling and typing tightened across DWARF/ELF/PECOFF modules and public APIs to surface real errors without masking them.
@@ -181,6 +184,14 @@ And loaded again...
181
184
  Section(address = 0X00001000, length = 16, data = b'Hello HEX world!')
182
185
  Section(address = 0X00002000, length = 16, data = b'\x01\x02\x03\x04\x05\x06\x07\x08\t\n\x0b\x0c\r\x0e\x0f\x10')
183
186
 
187
+ Or split it into its sections...
188
+
189
+ .. code-block:: python
190
+
191
+ images = img1.split()
192
+ for i, img in enumerate(images):
193
+ dump("srec", f"part_{i}.srec", img)
194
+
184
195
  This leads to the conversion idiom.
185
196
 
186
197
  .. code-block:: python
@@ -278,22 +278,19 @@ oj_hex_info
278
278
 
279
279
  .. code-block:: shell
280
280
 
281
- usage: oj-hex-info [-h] [-d]
282
- {ash,cosmac,emon52,etek,fpc,ihex,mostec,rca,shf,sig,srec,tek,titxt}
283
- hex_file
281
+ usage: oj-hex-info [-h] [-d] [-p]
282
+ [file_type] hex_file
284
283
 
285
284
  Displays informations about HEX files.
286
285
 
287
286
  positional arguments:
288
- {ash,cosmac,emon52,etek,fpc,ihex,mostec,rca,shf,sig,srec,tek,titxt}
289
- file type
287
+ file_type file type (optional, if omitted it is probed)
290
288
  hex_file HEX file
291
289
 
292
290
  optional arguments:
293
291
  -h, --help show this help message and exit
294
292
  -d, --dump hexdump contents
295
-
296
- Filetype is a required argument (no auto-probing yet).
293
+ -p, --print-filename Print filename including path
297
294
 
298
295
  Run it as follows:
299
296
 
@@ -301,8 +298,9 @@ Without any optional arguments just the addresses and lengths of the contained s
301
298
 
302
299
  .. code-block:: shell
303
300
 
304
- $ oj_hex_info srec sample.srec
301
+ $ oj-hex-info sample.srec
305
302
 
303
+ Sections
306
304
  --------
307
305
 
308
306
  Num Address Length
@@ -316,7 +314,7 @@ If you also want to see the contents, add *-d* option:
316
314
 
317
315
  .. code-block:: shell
318
316
 
319
- $ oj_hex_info srec sample.srec -d
317
+ $ oj-hex-info sample.srec -d
320
318
 
321
319
  Sections
322
320
  --------
@@ -342,6 +340,78 @@ If you also want to see the contents, add *-d* option:
342
340
  16 bytes
343
341
  ---------------
344
342
 
343
+ oj_hex_merge
344
+ ------------
345
+
346
+ .. code-block:: shell
347
+
348
+ usage: oj-hex-merge [-h] -o OUTPUT [-t OUTPUT_TYPE] [-p] [-v]
349
+ input_files [input_files ...]
350
+
351
+ Merges multiple HEX files into one.
352
+
353
+ positional arguments:
354
+ input_files Input HEX files to be merged.
355
+
356
+ optional arguments:
357
+ -h, --help show this help message and exit
358
+ -o OUTPUT, --output OUTPUT
359
+ Output HEX file.
360
+ -t OUTPUT_TYPE, --type OUTPUT_TYPE
361
+ Output file type (e.g., ihex, srec). If omitted, it's
362
+ inferred from the output file extension.
363
+ -p, --print-filename Print filenames while processing
364
+ -v, --verbose Verbose output
365
+
366
+ Example:
367
+
368
+ .. code-block:: shell
369
+
370
+ $ oj-hex-merge file1.hex file2.hex -o merged.hex
371
+
372
+ Note: Merging files with overlapping sections is not allowed and will result in an error.
373
+
374
+ oj_hex_split
375
+ ------------
376
+
377
+ .. code-block:: shell
378
+
379
+ usage: oj-hex-split [-h] [-o OUTPUT_NAMES [OUTPUT_NAMES ...]]
380
+ [-t OUTPUT_TYPE] [-p PREFIX] [-v]
381
+ input_file
382
+
383
+ Splits a HEX file into multiple files based on its sections.
384
+
385
+ positional arguments:
386
+ input_file Input HEX file to be split.
387
+
388
+ optional arguments:
389
+ -h, --help show this help message and exit
390
+ -o OUTPUT_NAMES [OUTPUT_NAMES ...], --output-names OUTPUT_NAMES [OUTPUT_NAMES ...]
391
+ Optional list of output base names. If not provided,
392
+ section numbers are used.
393
+ -t OUTPUT_TYPE, --type OUTPUT_TYPE
394
+ Output file type (e.g., ihex, srec). If omitted, it's
395
+ inferred from the input file extension.
396
+ -p PREFIX, --prefix PREFIX
397
+ Prefix for output filenames. Defaults to input
398
+ filename (without extension).
399
+ -v, --verbose Verbose output
400
+
401
+ Example:
402
+
403
+ .. code-block:: shell
404
+
405
+ $ oj-hex-split merged.hex
406
+
407
+ This will generate files like ``merged_000.hex``, ``merged_001.hex``, etc.
408
+
409
+ You can also specify custom names:
410
+
411
+ .. code-block:: shell
412
+
413
+ $ oj-hex-split merged.hex -o code data
414
+
345
415
  oj_coff_info
346
416
  ------------
347
417
 
@@ -13,7 +13,7 @@ Registers CODECS and implements an interface to them.
13
13
  The first parameter is always the codec name.
14
14
  """
15
15
 
16
- __version__ = "0.10.11"
16
+ __version__ = "0.10.13"
17
17
 
18
18
  __all__ = [
19
19
  "Image",
@@ -165,6 +165,10 @@ Usage Examples
165
165
  if 0x1050 in img:
166
166
  data = img.read(0x1050, 16)
167
167
 
168
+ # Check if address range is fully contained
169
+ if img.contains_range(0x1000, 0x100):
170
+ data = img.read(0x1000, 0x100)
171
+
168
172
  # Iterate over sections
169
173
  for section in img:
170
174
  print(f"Section at 0x{section.start_address:08X}, "
@@ -468,8 +472,61 @@ class Image:
468
472
  return not (self == other)
469
473
 
470
474
  def __contains__(self, addr: int) -> bool:
471
- """Check if address is contained in any section."""
472
- return any(addr in sec for sec in self.sections)
475
+ """Check if address is contained in any section of the image.
476
+
477
+ Args:
478
+ addr: Address to check.
479
+
480
+ Returns:
481
+ True if the address is within any section, False otherwise.
482
+ """
483
+ return any(addr in section for section in self.sections)
484
+
485
+ def contains_range(self, addr: int, size: int) -> bool:
486
+ """Check if address range is fully contained in the image.
487
+
488
+ Args:
489
+ addr: Start address of the range.
490
+ size: Size of the range.
491
+
492
+ Returns:
493
+ True if the entire range [addr, addr + size) is covered by sections.
494
+ """
495
+ if size < 0:
496
+ return False
497
+ if size == 0:
498
+ return addr in self
499
+
500
+ # Check if the range is covered by sections.
501
+ # Since sections are sorted and non-overlapping, we can check continuity.
502
+ remaining_size = size
503
+ current_addr = addr
504
+
505
+ # Find the first section that could contain current_addr
506
+ import bisect
507
+ from operator import attrgetter
508
+ idx = bisect.bisect_right(self.sections, current_addr, key=attrgetter("start_address")) - 1
509
+ if idx < 0:
510
+ idx = 0
511
+
512
+ while idx < len(self.sections) and remaining_size > 0:
513
+ section = self.sections[idx]
514
+ if current_addr < section.start_address:
515
+ # Gap before this section
516
+ return False
517
+
518
+ if current_addr < section.start_address + len(section):
519
+ # current_addr is in this section
520
+ covered = min(remaining_size, (section.start_address + len(section)) - current_addr)
521
+ remaining_size -= covered
522
+ current_addr += covered
523
+ else:
524
+ # current_addr is beyond this section
525
+ pass
526
+
527
+ idx += 1
528
+
529
+ return remaining_size == 0
473
530
 
474
531
  def hexdump(self, fp=sys.stdout) -> None:
475
532
  """Print hexadecimal dump of all sections.
@@ -818,16 +875,21 @@ class Image:
818
875
  self._call_address_function("write_string", addr, value, encoding, **kws)
819
876
 
820
877
  def _address_contained(self, address: int, length: int) -> bool:
821
- """Check if address range is contained in the image.
878
+ """Check if address range has ANY overlap with the image.
822
879
 
823
880
  Args:
824
881
  address: Start address to check.
825
882
  length: Length of the address range.
826
883
 
827
884
  Returns:
828
- True if the address range is contained in any section, False otherwise.
885
+ True if the address range overlaps with any section, False otherwise.
829
886
  """
830
- return address in self or (address + length - 1) in self
887
+ if length <= 0:
888
+ return False
889
+ end = address + length
890
+ # A range [address, end) overlaps with [s.start, s.end) if:
891
+ # address < s.end AND s.start < end
892
+ return any(address < (s.start_address + len(s)) and s.start_address < end for s in self.sections)
831
893
 
832
894
  def insert_section(
833
895
  self, data: Union[bytes, bytearray, memoryview, str], start_address: Optional[int] = None, join: bool = True
@@ -901,6 +963,8 @@ class Image:
901
963
  This method currently only validates the address range but does not
902
964
  perform the actual update operation. Full implementation is pending.
903
965
  """
966
+ if address is None:
967
+ address = self.address
904
968
  if not self._address_contained(address, len(data)):
905
969
  raise InvalidAddressError("Address-space not in range")
906
970
 
@@ -940,23 +1004,13 @@ class Image:
940
1004
  if not (new_address + len(section) <= s.start_address or new_address >= s.start_address + len(s)):
941
1005
  raise InvalidAddressError(f"New address 0x{new_address:08x} causes overlap with section at 0x{s.start_address:08x}")
942
1006
 
943
- def split(self, at: Optional[int] = None, equal_parts: Optional[int] = None, remap: Optional[bool] = None) -> None:
944
- """Split image into multiple parts.
945
-
946
- Args:
947
- at: Address at which to split the image.
948
- equal_parts: Number of equal-sized parts to split into.
949
- remap: If True, remap addresses after splitting.
950
-
951
- Raises:
952
- NotImplementedError: This method is not yet implemented.
1007
+ def split(self) -> list["Image"]:
1008
+ """Split image into multiple parts based on sections.
953
1009
 
954
- Note:
955
- This method is currently a placeholder and needs to be fully
956
- implemented for production use. The parameters define different
957
- splitting strategies that need to be developed.
1010
+ Returns:
1011
+ List of Image objects, each containing exactly one section.
958
1012
  """
959
- raise NotImplementedError(f"split() is not yet implemented. Called with: at={at}, equal_parts={equal_parts}, remap={remap}")
1013
+ return [Image([section], join=False) for section in self.sections]
960
1014
 
961
1015
 
962
1016
  def _validate_sections(sections: Iterable[Section]) -> None:
@@ -4,7 +4,7 @@
4
4
  __copyright__ = """
5
5
  objutils - Object file library for Python.
6
6
 
7
- (C) 2010-2020 by Christoph Schueler <cpu12.gems@googlemail.com>
7
+ (C) 2010-2026 by Christoph Schueler <cpu12.gems@googlemail.com>
8
8
 
9
9
  All Rights Reserved
10
10
 
@@ -0,0 +1,130 @@
1
+ #!/usr/bin/env python
2
+ """Merges multiple HEX files into one."""
3
+
4
+ __copyright__ = """
5
+ objutils - Object file library for Python.
6
+
7
+ (C) 2010-2026 by Christoph Schueler <cpu12.gems@googlemail.com>
8
+
9
+ All Rights Reserved
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation; either version 2 of the License, or
14
+ (at your option) any later version.
15
+
16
+ This program is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License along
22
+ with this program; if not, write to the Free Software Foundation, Inc.,
23
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
+ """
25
+
26
+ import argparse
27
+ import sys
28
+ from os import path
29
+
30
+ from objutils import load, probe, dump, Image
31
+
32
+
33
+ def main():
34
+ parser = argparse.ArgumentParser(description="Merges multiple HEX files into one.")
35
+ parser.add_argument(
36
+ "input_files",
37
+ nargs="+",
38
+ help="Input HEX files to be merged.",
39
+ )
40
+ parser.add_argument(
41
+ "-o",
42
+ "--output",
43
+ required=True,
44
+ help="Output HEX file.",
45
+ )
46
+ parser.add_argument(
47
+ "-t",
48
+ "--type",
49
+ dest="output_type",
50
+ help="Output file type (e.g., ihex, srec). If omitted, it's inferred from the output file extension.",
51
+ )
52
+ parser.add_argument(
53
+ "-p",
54
+ "--print-filename",
55
+ dest="print_filename",
56
+ action="store_true",
57
+ default=False,
58
+ help="Print filenames while processing",
59
+ )
60
+ parser.add_argument(
61
+ "-v",
62
+ "--verbose",
63
+ dest="verbose",
64
+ action="store_true",
65
+ default=False,
66
+ help="Verbose output",
67
+ )
68
+
69
+ args = parser.parse_args()
70
+
71
+ output_type = args.output_type
72
+ if not output_type:
73
+ ext = path.splitext(args.output)[1].lower()
74
+ if ext in (".hex", ".ihex"):
75
+ output_type = "ihex"
76
+ elif ext in (".s19", ".srec", ".mot"):
77
+ output_type = "srec"
78
+ elif ext in (".bin",):
79
+ output_type = "bin"
80
+ else:
81
+ print(f"Could not infer output type from extension '{ext}'. Please specify with -t.")
82
+ sys.exit(1)
83
+
84
+ all_sections = []
85
+
86
+ for filename in args.input_files:
87
+ if not path.exists(filename):
88
+ print(f"File '{filename}' does not exist.")
89
+ sys.exit(1)
90
+
91
+ if args.print_filename:
92
+ print(f"Processing '{filename}'...")
93
+
94
+ with open(filename, "rb") as f:
95
+ file_type = probe(f)
96
+
97
+ if file_type is None:
98
+ print(f"Could not determine file type for '{filename}'.")
99
+ sys.exit(1)
100
+
101
+ img = load(file_type, filename)
102
+ for section in img:
103
+ # Check for overlaps manually to satisfy "No overlaps allowed during merge"
104
+ for existing in all_sections:
105
+ if not (
106
+ section.start_address + section.length <= existing.start_address
107
+ or section.start_address >= existing.start_address + existing.length
108
+ ):
109
+ overlap_start = max(section.start_address, existing.start_address)
110
+ print(f"Error: Overlap detected at 0x{overlap_start:08x} between input files.")
111
+ sys.exit(1)
112
+ all_sections.append(section)
113
+
114
+ merged_image = Image(all_sections, join=True)
115
+
116
+ if args.verbose:
117
+ print("\nMerged Image Sections:")
118
+ print("Num Address Length")
119
+ print("-" * 79)
120
+ for idx, sec in enumerate(merged_image):
121
+ print(f"{idx:03d} 0x{sec.start_address:08x} {sec.length}")
122
+ print("-" * 79)
123
+ print(f" {len(merged_image)} total bytes")
124
+
125
+ dump(output_type, args.output, merged_image)
126
+ print(f"Successfully merged into '{args.output}' (type: {output_type}).")
127
+
128
+
129
+ if __name__ == "__main__":
130
+ main()
@@ -0,0 +1,138 @@
1
+ #!/usr/bin/env python
2
+ """Splits a HEX file into multiple files based on its sections."""
3
+
4
+ __copyright__ = """
5
+ objutils - Object file library for Python.
6
+
7
+ (C) 2010-2026 by Christoph Schueler <cpu12.gems@googlemail.com>
8
+
9
+ All Rights Reserved
10
+
11
+ This program is free software; you can redistribute it and/or modify
12
+ it under the terms of the GNU General Public License as published by
13
+ the Free Software Foundation; either version 2 of the License, or
14
+ (at your option) any later version.
15
+
16
+ This program is distributed in the hope that it will be useful,
17
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
18
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19
+ GNU General Public License for more details.
20
+
21
+ You should have received a copy of the GNU General Public License along
22
+ with this program; if not, write to the Free Software Foundation, Inc.,
23
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
+ """
25
+
26
+ import argparse
27
+ import sys
28
+ from os import path
29
+ from pathlib import Path
30
+
31
+ from objutils import load, probe, dump
32
+ from ufilename import build_filename, SuffixPolicy, IdentityPolicy
33
+
34
+
35
+ def main():
36
+ parser = argparse.ArgumentParser(description="Splits a HEX file into multiple files based on its sections.")
37
+ parser.add_argument(
38
+ "input_file",
39
+ help="Input HEX file to be split.",
40
+ )
41
+ parser.add_argument(
42
+ "-o",
43
+ "--output-names",
44
+ nargs="+",
45
+ help="Optional list of output base names. If not provided, section numbers are used.",
46
+ )
47
+ parser.add_argument(
48
+ "-t",
49
+ "--type",
50
+ dest="output_type",
51
+ help="Output file type (e.g., ihex, srec). If omitted, it's inferred from the input file extension.",
52
+ )
53
+ parser.add_argument(
54
+ "-p",
55
+ "--prefix",
56
+ help="Prefix for output filenames. Defaults to input filename (without extension).",
57
+ )
58
+ parser.add_argument(
59
+ "-v",
60
+ "--verbose",
61
+ dest="verbose",
62
+ action="store_true",
63
+ default=False,
64
+ help="Verbose output",
65
+ )
66
+
67
+ args = parser.parse_args()
68
+
69
+ if not path.exists(args.input_file):
70
+ print(f"File '{args.input_file}' does not exist.")
71
+ sys.exit(1)
72
+
73
+ with open(args.input_file, "rb") as f:
74
+ file_type = probe(f)
75
+
76
+ if file_type is None:
77
+ print(f"Could not determine file type for '{args.input_file}'.")
78
+ sys.exit(1)
79
+
80
+ img = load(file_type, args.input_file)
81
+
82
+ if not img.sections:
83
+ print(f"No sections found in '{args.input_file}'.")
84
+ sys.exit(0)
85
+
86
+ output_type = args.output_type
87
+ input_path = Path(args.input_file)
88
+ if not output_type:
89
+ ext = input_path.suffix.lower()
90
+ if ext in (".hex", ".ihex"):
91
+ output_type = "ihex"
92
+ elif ext in (".s19", ".srec", ".mot"):
93
+ output_type = "srec"
94
+ elif ext in (".bin",):
95
+ output_type = "bin"
96
+ else:
97
+ output_type = "ihex" # Fallback
98
+
99
+ base_prefix = args.prefix if args.prefix else input_path.stem
100
+ output_ext = input_path.suffix if not args.output_type else f".{args.output_type}"
101
+ # Normalize extension mapping for ufilename
102
+ if args.output_type:
103
+ if args.output_type == "ihex":
104
+ output_ext = ".hex"
105
+ elif args.output_type == "srec":
106
+ output_ext = ".s19"
107
+ elif args.output_type == "bin":
108
+ output_ext = ".bin"
109
+
110
+ if args.verbose:
111
+ print(f"Splitting '{args.input_file}' into {len(img.sections)} sections...")
112
+
113
+ split_images = img.split()
114
+
115
+ for idx, new_img in enumerate(split_images):
116
+ section = new_img.sections[0]
117
+ if args.output_names and idx < len(args.output_names):
118
+ # User provided a list of names
119
+ name_policy = IdentityPolicy()
120
+ out_base = args.output_names[idx]
121
+ else:
122
+ # Default: append section number
123
+ name_policy = SuffixPolicy(suffix=f"_{idx:03d}")
124
+ out_base = base_prefix
125
+
126
+ out_filename = build_filename(name_policy, out_base, output_ext)
127
+
128
+ print(f"Writing '{out_filename}'...")
129
+ if args.verbose:
130
+ print(f" Section {idx:03d} (0x{section.start_address:08x}, {len(section)} bytes)")
131
+
132
+ dump(output_type, out_filename, new_img)
133
+
134
+ print(f"Successfully split into {len(split_images)} files.")
135
+
136
+
137
+ if __name__ == "__main__":
138
+ main()