hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 46d0b88eff89c5b054e238f0c299ca99f5201338
parent 7820b93c0fcf6cc0784bec297e55f0302b0a6b52
Author: Alexey Yerin <yyp@disroot.org>
Date:   Sun, 28 Mar 2021 17:11:32 +0300

Add encoding::hex::dump

Diffstat:
Mencoding/hex/hex.ha | 54++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mscripts/gen-stdlib | 2+-
Mstdlib.mk | 4++--
3 files changed, 57 insertions(+), 3 deletions(-)

diff --git a/encoding/hex/hex.ha b/encoding/hex/hex.ha @@ -1,4 +1,6 @@ +use ascii; use bytes; +use fmt; use io; use strconv; use strings; @@ -61,3 +63,55 @@ export fn decode(s: str) ([]u8 | invalid) = { decode("this is not hex") as invalid; }; + +// Outputs a dump of hex data to a stream alongside the offset and an ASCII +// representation (if applicable). +// +// Example output: +// +// 00000000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 |.ELF............| +// 00000010 03 00 3e 00 01 00 00 00 80 70 01 00 00 00 00 00 |..>......p......| +export fn dump(out: *io::stream, data: []u8) (void | io::error) = { + let datalen = len(data): u32; + + for (let off = 0u32; off < datalen; off += 16) { + fmt::fprintf(out, "{:08x} ", off)?; + + let toff = 0z; + for (let i = 0z; i < 16 && off + i < datalen; i += 1) { + let val = data[off + i]; + toff += fmt::fprintf(out, "{}{:02x} ", + if (i == 8) " " else "", val)?; + }; + + // Align ASCII representation, max width of hex part (48) + + // spacing around it + for (toff < 50; toff += 1) { + fmt::fprint(out, " ")?; + }; + + fmt::fprint(out, "|")?; + for (let i = 0z; i < 16 && off + i < datalen; i += 1) { + let r = data[off + i]: u32: rune; + + fmt::fprint(out, if (ascii::isprint(r)) r else '.')?; + }; + fmt::fprint(out, "|\n")?; + }; +}; + +@test fn dump() void = { + let in: [_]u8 = [ + 0x7F, 0x45, 0x4c, 0x46, 0x02, 0x01, 0x01, 0x00, 0xCA, 0xFE, + 0xBA, 0xBE, 0xDE, 0xAD, 0xF0, 0x0D, 0xCE, 0xFE, 0xBA, 0xBE, + 0xDE, 0xAD, 0xF0, 0x0D + ]; + + let sink = strio::dynamic(); + dump(sink, in) as void; + + let s = strio::finish(sink); + assert(s == + "00000000 7f 45 4c 46 02 01 01 00 ca fe ba be de ad f0 0d |.ELF............|\n" + "00000010 ce fe ba be de ad f0 0d |........|\n"); +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -200,7 +200,7 @@ encoding_hex() { printf '# encoding::hex\n' gen_srcs encoding::hex \ hex.ha - gen_ssa encoding::hex io strconv strio strings bytes + gen_ssa encoding::hex ascii bytes fmt io strconv strio strings } encoding_utf8() { diff --git a/stdlib.mk b/stdlib.mk @@ -295,7 +295,7 @@ $(HARECACHE)/dirs/dirs.ssa: $(stdlib_dirs_srcs) $(stdlib_rt) $(stdlib_fs) $(stdl stdlib_encoding_hex_srcs= \ $(STDLIB)/encoding/hex/hex.ha -$(HARECACHE)/encoding/hex/encoding_hex.ssa: $(stdlib_encoding_hex_srcs) $(stdlib_rt) $(stdlib_io) $(stdlib_strconv) $(stdlib_strio) $(stdlib_strings) $(stdlib_bytes) +$(HARECACHE)/encoding/hex/encoding_hex.ssa: $(stdlib_encoding_hex_srcs) $(stdlib_rt) $(stdlib_ascii) $(stdlib_bytes) $(stdlib_fmt) $(stdlib_io) $(stdlib_strconv) $(stdlib_strio) $(stdlib_strings) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/encoding/hex @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nencoding::hex \ @@ -986,7 +986,7 @@ $(TESTCACHE)/dirs/dirs.ssa: $(testlib_dirs_srcs) $(testlib_rt) $(testlib_fs) $(t testlib_encoding_hex_srcs= \ $(STDLIB)/encoding/hex/hex.ha -$(TESTCACHE)/encoding/hex/encoding_hex.ssa: $(testlib_encoding_hex_srcs) $(testlib_rt) $(testlib_io) $(testlib_strconv) $(testlib_strio) $(testlib_strings) $(testlib_bytes) +$(TESTCACHE)/encoding/hex/encoding_hex.ssa: $(testlib_encoding_hex_srcs) $(testlib_rt) $(testlib_ascii) $(testlib_bytes) $(testlib_fmt) $(testlib_io) $(testlib_strconv) $(testlib_strio) $(testlib_strings) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/encoding/hex @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nencoding::hex \