Skip to content

Commit

Permalink
Added xxd example tests from original manual
Browse files Browse the repository at this point in the history
Signed-off-by: Andrea Zoppi <texzk@email.it>
  • Loading branch information
TexZK committed Mar 6, 2024
1 parent 4c24ef7 commit 68fb93c
Show file tree
Hide file tree
Showing 27 changed files with 6,130 additions and 18 deletions.
8 changes: 4 additions & 4 deletions src/hexrec/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -681,7 +681,7 @@ def flood(
expose_value=False, callback=print_hexdump_version, help="""
Print version and exit.
""")
@click.argument('infile', type=FILE_PATH_IN)
@click.argument('infile', type=FILE_PATH_IN, required=False)
def hexdump(
infile: str,
one_byte_octal: Sequence[bool],
Expand Down Expand Up @@ -812,7 +812,7 @@ def hexdump(
expose_value=False, callback=print_hexdump_version, help="""
Print version and exit.
""")
@click.argument('infile', type=FILE_PATH_IN)
@click.argument('infile', type=FILE_PATH_IN, required=False)
def hd(
infile: str,
one_byte_octal: Sequence[bool],
Expand Down Expand Up @@ -1219,8 +1219,8 @@ def del_header(
expose_value=False, callback=print_version, help="""
Prints the package version number.
""")
@click.argument('infile', type=FILE_PATH_IN)
@click.argument('outfile', type=FILE_PATH_OUT)
@click.argument('infile', type=FILE_PATH_IN, required=False)
@click.argument('outfile', type=FILE_PATH_OUT, required=False)
def xxd(
autoskip: bool,
bits: bool,
Expand Down
31 changes: 19 additions & 12 deletions src/hexrec/xxd.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,8 @@
_SEEKING_REGEX = re.compile(r'^(?P<sign>\+?-?)-?(?P<absolute>\w+)$')

_REVERSE_REGEX = re.compile(b'^\\s*(?P<address>[A-Fa-f0-9]+)\\s*:\\s*'
b'(?P<data>([A-Fa-f0-9]{2}\\s*)+)'
b'[ ]{2}(?P<garbage>.*)$')
b'(?P<data>([A-Fa-f0-9]{2}\\s?)+)'
b'(\\s.*)?$')

ZERO_BLOCK_SIZE = 1 << 20 # 1 MiB

Expand Down Expand Up @@ -344,7 +344,8 @@ def xxd_core(
outfile = None
outstream = sys.stdout.buffer
elif isinstance(outfile, str):
outstream = open(outfile, 'w+b' if revert and oseek else 'wb')
mode = 'r+b' if revert and os.path.exists(outfile) else 'wb'
outstream = open(outfile, mode)
elif isinstance(outfile, MutableMemory):
outstream = SparseMemoryIO(memory=outfile)
outsparse = True
Expand All @@ -357,14 +358,20 @@ def xxd_core(
if iseek is not None:
ss, sv = parse_seek(str(iseek))

if ss == '+':
instream.seek(sv, io.SEEK_CUR)
elif ss == '+-':
instream.seek(-sv, io.SEEK_CUR)
elif ss == '-':
instream.seek(-sv, io.SEEK_END)
else: # elif ss == '':
instream.seek(sv, io.SEEK_SET)
if revert:
if '-' in ss:
sv = -sv
iseek = sv

else:
if ss == '+':
instream.seek(sv, io.SEEK_CUR)
elif ss == '+-':
instream.seek(-sv, io.SEEK_CUR)
elif ss == '-':
instream.seek(-sv, io.SEEK_END)
else: # elif ss == '':
instream.seek(sv, io.SEEK_SET)

offset += instream.tell()

Expand All @@ -391,7 +398,7 @@ def xxd_core(
if match:
# Interpret line contents
groups = match.groupdict()
address = (oseek or 0) + int(groups['address'], 16)
address = (oseek or 0) + (iseek or 0) + int(groups['address'], 16)
data = _unhexlify(groups['data'])
data = data[:cols]

Expand Down
31 changes: 29 additions & 2 deletions tests/test_xxd.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import glob
import io
import os
import shutil
import sys
from pathlib import Path
from typing import Any
Expand Down Expand Up @@ -72,7 +73,7 @@ def test_by_filename_text(tmppath, datapath):

for filename in test_filenames:
filename = os.path.basename(filename)
print(filename)
print('@', filename, file=sys.stderr)
path_out = tmppath / filename
path_ref = datapath / filename

Expand All @@ -92,12 +93,20 @@ def test_by_filename_text(tmppath, datapath):


def test_by_filename_bytes(tmppath, datapath):
copy_filenames = [
(r'xxd.1', r'test_xxd_-r_xxd.1.patch.xxd.bin'),
]
for path_ref, path_out in copy_filenames:
path_ref = str(datapath / path_ref)
path_out = str(tmppath / path_out)
shutil.copy(path_ref, path_out)

prefix = 'test_xxd_'
test_filenames = glob.glob(str(datapath / (prefix + '*.bin')))

for filename in test_filenames:
filename = os.path.basename(filename)
print(filename)
print('@', filename, file=sys.stderr)
path_out = tmppath / filename
path_ref = datapath / filename

Expand Down Expand Up @@ -240,6 +249,24 @@ def test_xxd_include_stdin(datapath):
assert text_out == text_ref


def test_xxd_include_stdin_cli(tmppath, datapath):
filename = 'xxd_-i_STDIN_file.c'
path_out = tmppath / filename
path_ref = datapath / filename
path_in = datapath / 'file'

args = 'xxd -i - '.split() + [str(path_out)]

runner = CliRunner()
data_in = read_bytes(path_in)
result = runner.invoke(_cast(Any, cli_main), args, input=data_in)
assert result.exit_code == 0

ans_out = read_text(path_out)
ans_ref = read_text(path_ref)
assert ans_out == ans_ref


def test_xxd_none(datapath):
with open(str(datapath / 'test_xxd_bytes.bin.xxd'), 'rb') as stream:
text_ref = stream.read().replace(b'\r\n', b'\n')
Expand Down
1 change: 1 addition & 0 deletions tests/test_xxd/A.bin
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
A
1 change: 1 addition & 0 deletions tests/test_xxd/A.xxd
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
010000: 41
Loading

0 comments on commit 68fb93c

Please sign in to comment.