hare

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

commit 316a40ee12d8b90ae1f676bbf195de32cb6f2fc1
parent 7dfb0145d6bc57177b0267a2e07d4a84e38eb659
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu, 25 Mar 2021 11:28:54 -0400

encoding::hex: support encoding to stream

Diffstat:
Mcmd/hare/schedule.ha | 2+-
Mencoding/hex/hex.ha | 23+++++++++++++++--------
Mhare/module/manifest.ha | 6+++---
Mscripts/gen-stdlib | 4++--
Mstdlib.mk | 8++++----
Mtemp/+linux.ha | 11++++++++---
6 files changed, 33 insertions(+), 21 deletions(-)

diff --git a/cmd/hare/schedule.ha b/cmd/hare/schedule.ha @@ -156,7 +156,7 @@ fn sched_hare_object( let current = false; let output = if (len(namespace) != 0) { - let version = hex::encode(ver.hash); + let version = hex::encodestr(ver.hash); let ns = unparse::identstr(namespace); let env = module::identuscore(namespace); defer free(env); diff --git a/encoding/hex/hex.ha b/encoding/hex/hex.ha @@ -7,23 +7,30 @@ use strio; // Error returned when attempting to decode an invalid hex string. export type invalid = void!; -// Encodes a byte slice to hex and writes it to a string. The caller must free -// this string. -export fn encode(b: []u8) str = { - let buf = strio::dynamic(); +// Encodes a byte slice as a hexadecimal string and writes it to a stream. +export fn encode(sink: *io::stream, b: []u8) (size | io::error) = { + let z = 0z; for (let i = 0z; i < len(b); i += 1) { let s = strconv::u8tosb(b[i], strconv::base::HEX_LOWER); if (len(s) == 1) { - io::write(buf, ['0': u32: u8]); + z += io::write(sink, ['0': u32: u8])?; }; - io::write(buf, strings::toutf8(s)) as size; + z += io::write(sink, strings::toutf8(s))?; }; - return strio::finish(buf); + return z; +}; + +// Encodes a byte slice as a hexadecimal string and returns it. The caller must +// free the return value. +export fn encodestr(b: []u8) str = { + let sink = strio::dynamic(); + encode(sink, b) as size; + return strio::finish(sink); }; @test fn encode() void = { let in: [_]u8 = [0xCA, 0xFE, 0xBA, 0xBE, 0xDE, 0xAD, 0xF0, 0x0D]; - let s = encode(in); + let s = encodestr(in); defer free(s); assert(s == "cafebabedeadf00d"); }; diff --git a/hare/module/manifest.ha b/hare/module/manifest.ha @@ -231,7 +231,7 @@ export fn manifest_write(ctx: *context, manifest: *manifest) (void | error) = { fmt::fprintfln(fd, "version {}", VERSION)?; for (let i = 0z; i < len(manifest.inputs); i += 1) { const input = manifest.inputs[i]; - let hash = hex::encode(input.hash); + let hash = hex::encodestr(input.hash); defer free(hash); const want = fs::stat_mask::INODE | fs::stat_mask::MTIME; @@ -243,13 +243,13 @@ export fn manifest_write(ctx: *context, manifest: *manifest) (void | error) = { for (let i = 0z; i < len(manifest.versions); i += 1) { const ver = manifest.versions[i]; - let hash = hex::encode(ver.hash); + let hash = hex::encodestr(ver.hash); defer free(hash); fmt::fprintf(fd, "module {}", hash); for (let j = 0z; j < len(ver.inputs); j += 1) { - let hash = hex::encode(ver.inputs[i].hash); + let hash = hex::encodestr(ver.inputs[i].hash); defer free(hash); fmt::fprintf(fd, " {}", hash); diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -295,7 +295,7 @@ hare_module() { gen_ssa hare::module \ hare::ast hare::lex hare::parse hare::unparse strio fs io strings hash \ crypto::sha256 dirs bytes encoding::utf8 ascii fmt time slice bufio \ - strconv os + strconv os encoding::hex } gensrcs_hare_parse() { @@ -512,7 +512,7 @@ temp() { printf '# temp\n' gen_srcs temp \ '$(PLATFORM).ha' - gen_ssa temp crypto::random encoding::hex fs io os path + gen_ssa temp crypto::random encoding::hex fs io os path strio } types() { diff --git a/stdlib.mk b/stdlib.mk @@ -383,7 +383,7 @@ stdlib_hare_module_srcs= \ $(STDLIB)/hare/module/scan.ha \ $(STDLIB)/hare/module/manifest.ha -$(HARECACHE)/hare/module/hare_module.ssa: $(stdlib_hare_module_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_lex) $(stdlib_hare_parse) $(stdlib_hare_unparse) $(stdlib_strio) $(stdlib_fs) $(stdlib_io) $(stdlib_strings) $(stdlib_hash) $(stdlib_crypto_sha256) $(stdlib_dirs) $(stdlib_bytes) $(stdlib_encoding_utf8) $(stdlib_ascii) $(stdlib_fmt) $(stdlib_time) $(stdlib_slice) $(stdlib_bufio) $(stdlib_strconv) $(stdlib_os) +$(HARECACHE)/hare/module/hare_module.ssa: $(stdlib_hare_module_srcs) $(stdlib_rt) $(stdlib_hare_ast) $(stdlib_hare_lex) $(stdlib_hare_parse) $(stdlib_hare_unparse) $(stdlib_strio) $(stdlib_fs) $(stdlib_io) $(stdlib_strings) $(stdlib_hash) $(stdlib_crypto_sha256) $(stdlib_dirs) $(stdlib_bytes) $(stdlib_encoding_utf8) $(stdlib_ascii) $(stdlib_fmt) $(stdlib_time) $(stdlib_slice) $(stdlib_bufio) $(stdlib_strconv) $(stdlib_os) $(stdlib_encoding_hex) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/hare/module @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Nhare::module \ @@ -606,7 +606,7 @@ $(HARECACHE)/strio/strio.ssa: $(stdlib_strio_srcs) $(stdlib_rt) $(stdlib_io) $(s stdlib_temp_srcs= \ $(STDLIB)/temp/$(PLATFORM).ha -$(HARECACHE)/temp/temp.ssa: $(stdlib_temp_srcs) $(stdlib_rt) $(stdlib_crypto_random) $(stdlib_encoding_hex) $(stdlib_fs) $(stdlib_io) $(stdlib_os) $(stdlib_path) +$(HARECACHE)/temp/temp.ssa: $(stdlib_temp_srcs) $(stdlib_rt) $(stdlib_crypto_random) $(stdlib_encoding_hex) $(stdlib_fs) $(stdlib_io) $(stdlib_os) $(stdlib_path) $(stdlib_strio) @printf 'HAREC \t$@\n' @mkdir -p $(HARECACHE)/temp @HARECACHE=$(HARECACHE) $(HAREC) $(HAREFLAGS) -o $@ -Ntemp \ @@ -1035,7 +1035,7 @@ testlib_hare_module_srcs= \ $(STDLIB)/hare/module/scan.ha \ $(STDLIB)/hare/module/manifest.ha -$(TESTCACHE)/hare/module/hare_module.ssa: $(testlib_hare_module_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_lex) $(testlib_hare_parse) $(testlib_hare_unparse) $(testlib_strio) $(testlib_fs) $(testlib_io) $(testlib_strings) $(testlib_hash) $(testlib_crypto_sha256) $(testlib_dirs) $(testlib_bytes) $(testlib_encoding_utf8) $(testlib_ascii) $(testlib_fmt) $(testlib_time) $(testlib_slice) $(testlib_bufio) $(testlib_strconv) $(testlib_os) +$(TESTCACHE)/hare/module/hare_module.ssa: $(testlib_hare_module_srcs) $(testlib_rt) $(testlib_hare_ast) $(testlib_hare_lex) $(testlib_hare_parse) $(testlib_hare_unparse) $(testlib_strio) $(testlib_fs) $(testlib_io) $(testlib_strings) $(testlib_hash) $(testlib_crypto_sha256) $(testlib_dirs) $(testlib_bytes) $(testlib_encoding_utf8) $(testlib_ascii) $(testlib_fmt) $(testlib_time) $(testlib_slice) $(testlib_bufio) $(testlib_strconv) $(testlib_os) $(testlib_encoding_hex) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/hare/module @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Nhare::module \ @@ -1265,7 +1265,7 @@ $(TESTCACHE)/strio/strio.ssa: $(testlib_strio_srcs) $(testlib_rt) $(testlib_io) testlib_temp_srcs= \ $(STDLIB)/temp/$(PLATFORM).ha -$(TESTCACHE)/temp/temp.ssa: $(testlib_temp_srcs) $(testlib_rt) $(testlib_crypto_random) $(testlib_encoding_hex) $(testlib_fs) $(testlib_io) $(testlib_os) $(testlib_path) +$(TESTCACHE)/temp/temp.ssa: $(testlib_temp_srcs) $(testlib_rt) $(testlib_crypto_random) $(testlib_encoding_hex) $(testlib_fs) $(testlib_io) $(testlib_os) $(testlib_path) $(testlib_strio) @printf 'HAREC \t$@\n' @mkdir -p $(TESTCACHE)/temp @HARECACHE=$(TESTCACHE) $(HAREC) $(TESTHAREFLAGS) -o $@ -Ntemp \ diff --git a/temp/+linux.ha b/temp/+linux.ha @@ -4,6 +4,7 @@ use fs; use io; use os; use path; +use strio; fn get_tmpdir() str = os::tryenv("TMPDIR", "/tmp"); @@ -55,10 +56,14 @@ export fn named( // // The caller must free the return value. export fn dir() str = { - let buf: [8]u8 = [0...]; + let buf: [8]u8 = [0...], name: [16]u8 = [0...]; random::buffer(buf[..]); - let name = hex::encode(buf); - defer free(name); + + let sink = strio::fixed(name); + defer io::close(sink); + hex::encode(sink, buf) as size; + let name = strio::string(sink); + let path = path::join(get_tmpdir(), name); match (os::mkdir(path)) { err: fs::error => abort("Could not create temp directory"),