hare

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

commit 95d6615246f3516dba5aa034be42d5f60eb52517
parent 6cfd76c32af6a597c60254b460bc2878cbf86b99
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 12 Nov 2021 10:11:53 +0100

io: add readitem, readitems

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Mhare/module/scan.ha | 2+-
Mio/types.ha | 15+++++++++++++--
Aio/util.ha | 27+++++++++++++++++++++++++++
Mscripts/gen-stdlib | 2++
Mstdlib.mk | 8++++++--
5 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/hare/module/scan.ha b/hare/module/scan.ha @@ -14,7 +14,7 @@ use sort; use strings; use strio; -def ABI_VERSION: u8 = 0; +def ABI_VERSION: u8 = 1; // Scans the files in a directory for eligible build inputs and returns a // [[version]] which includes all applicable files and their dependencies. diff --git a/io/types.ha b/io/types.ha @@ -1,13 +1,24 @@ use errors; +// Returned by [[readitem]] and [[readitems]] if the I/O handle returned [[EOF]] +// prior to completely reading an item. +export type underread = !void; + // Any error which may be returned from an I/O function. -export type error = !errors::error; +export type error = !(errors::error | underread); // Indicates an end-of-file condition. export type EOF = void; // Converts an I/O [[error]] into a user-friendly string. -export fn strerror(err: error) str = errors::strerror(err); +export fn strerror(err: error) str = { + match (err) { + case underread => + return "Insufficient data to read entire item"; + case err: errors::error => + return errors::strerror(err); + }; +}; // Used to indicate if a stream should be used for reading, or writing, or both. export type mode = enum u8 { diff --git a/io/util.ha b/io/util.ha @@ -0,0 +1,27 @@ +// Reads an entire "item", i.e. one Hare object, from an I/O handle. This +// function may use multiple reads, but if [[EOF]] is encountered before the +// entire object is read, an [[underread]] error is returned. Otherwise, the +// return value is the total number of bytes read (which shall be equal to +// itemsz). +export fn readitem(in: handle, item: *void, itemsz: size) (size | error) = { + let buf = item: *[*]u8; + let i = 0z; + for (i < itemsz) { + match (io::read(in, buf[..(itemsz - i)])) { + case io::EOF => + return underread; + case z: size => + i += z; + }; + }; + return i; +}; + +// Reads several "items", i.e. Hare objects, from an I/O handle. If [[EOF]] is +// returned prior to reading all of the items completely, an [[underread]] error +// is returned. Otherwise, the return value is the number of items read. +export fn readitems(in: handle, items: []void, itemsz: size) (size | error) = { + let buf = items: *[*]u8; + readitem(in, buf, len(items) * itemsz)?; + return len(items); +}; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -606,6 +606,7 @@ gensrcs_io() { stream.ha \ tee.ha \ types.ha \ + util.ha \ $* gen_srcs -pfreebsd io \ 'arch+$(ARCH).ha' \ @@ -621,6 +622,7 @@ gensrcs_io() { stream.ha \ tee.ha \ types.ha \ + util.ha \ $* } diff --git a/stdlib.mk b/stdlib.mk @@ -1067,7 +1067,8 @@ stdlib_io_linux_srcs= \ $(STDLIB)/io/limit.ha \ $(STDLIB)/io/stream.ha \ $(STDLIB)/io/tee.ha \ - $(STDLIB)/io/types.ha + $(STDLIB)/io/types.ha \ + $(STDLIB)/io/util.ha # io (+freebsd) stdlib_io_freebsd_srcs= \ @@ -1083,7 +1084,8 @@ stdlib_io_freebsd_srcs= \ $(STDLIB)/io/limit.ha \ $(STDLIB)/io/stream.ha \ $(STDLIB)/io/tee.ha \ - $(STDLIB)/io/types.ha + $(STDLIB)/io/types.ha \ + $(STDLIB)/io/util.ha $(HARECACHE)/io/io-linux.ssa: $(stdlib_io_linux_srcs) $(stdlib_rt) $(stdlib_strings_$(PLATFORM)) $(stdlib_errors_$(PLATFORM)) @printf 'HAREC \t$@\n' @@ -2755,6 +2757,7 @@ testlib_io_linux_srcs= \ $(STDLIB)/io/stream.ha \ $(STDLIB)/io/tee.ha \ $(STDLIB)/io/types.ha \ + $(STDLIB)/io/util.ha \ $(STDLIB)/io/+test/copy.ha \ $(STDLIB)/io/+test/limit.ha \ $(STDLIB)/io/+test/stream.ha @@ -2774,6 +2777,7 @@ testlib_io_freebsd_srcs= \ $(STDLIB)/io/stream.ha \ $(STDLIB)/io/tee.ha \ $(STDLIB)/io/types.ha \ + $(STDLIB)/io/util.ha \ $(STDLIB)/io/+test/copy.ha \ $(STDLIB)/io/+test/limit.ha \ $(STDLIB)/io/+test/stream.ha