commit e15652b32701ef43535fe018f05ebf6f3718ecfc
parent c9539e8692cc24b57424e44afb4d7985454e5ef5
Author: Drew DeVault <sir@cmpwn.com>
Date: Wed, 24 Feb 2021 12:23:55 -0500
Flesh out bufio, strio some more
Diffstat:
4 files changed, 18 insertions(+), 5 deletions(-)
diff --git a/bufio/fixed.ha b/bufio/fixed.ha
@@ -8,7 +8,8 @@ type fixed_stream = struct {
};
// Creates an [io::stream] for a fixed, caller-supplied buffer. Supports either
-// read or write, but not both.
+// read or write, but not both. The program aborts if writes would exceed the
+// buffer's capacity.
export fn fixed(in: []u8, mode: io::mode) *io::stream = {
let s = alloc(fixed_stream {
stream = io::stream {
@@ -42,7 +43,7 @@ fn fixed_read(s: *io::stream, buf: []u8) (size | io::error | io::EOF) = {
fn fixed_write(s: *io::stream, buf: const []u8) (size | io::error) = {
let stream = s: *fixed_stream;
if (len(stream.buf) == 0) {
- return 0z;
+ abort("bufio::fixed buffer exceeded");
};
const n = if (len(buf) > len(stream.buf)) len(stream.buf) else len(buf);
stream.buf[..n] = buf[..n];
diff --git a/fmt/fmt.ha b/fmt/fmt.ha
@@ -75,6 +75,14 @@ export fn asprintf(fmt: str, args: formattable...) str = {
return strings::from_utf8_unsafe(bufio::buffer(buf) as []u8);
};
+// Formats text for printing and writes it into a caller supplied buffer. The
+// returned string is borrowed from this buffer.
+export fn bsprintf(buf: []u8, fmt: str, args: formattable...) str = {
+ let sink = bufio::fixed(buf, io::mode::WRITE);
+ assert(fprintf(sink, fmt, args...) is size);
+ return strings::from_utf8_unsafe(buf);
+};
+
// Formats text for printing and writes it to [os::stderr], followed by a line
// feed, then exits the program with an error status.
export @noreturn fn fatal(fmt: str, args: formattable...) void = {
diff --git a/hare/lex/lex.ha b/hare/lex/lex.ha
@@ -1,6 +1,7 @@
// hare::lex provides a lexer for Hare source code.
use ascii;
use encoding::utf8;
+use fmt;
use io;
use sort;
use strconv;
@@ -21,10 +22,13 @@ export type syntax = (location, str)!;
// All possible lexer errors
export type error = (io::error | syntax)!;
+// Returns a human-friendly string for a given error
export fn errstr(err: error) const str = {
+ static let buf: [2048]u8 = [0...];
return match (err) {
err: io::error => io::errstr(err),
- s: syntax => s.1, // TODO: format me
+ s: syntax => fmt::bsprintf(buf, "Syntax error @{}:{},{}: {}",
+ s.0.path, s.0.line, s.0.col, s.1),
};
};
diff --git a/strio/buffer.ha b/strio/buffer.ha
@@ -8,7 +8,7 @@ type fixed_stream = struct {
};
// Creates a write-only string stream using the provided buffer for storage.
-// The buffer will not be expanded if the writes exceed its capacity.
+// The program aborts if writes would exceed the buffer's capacity.
export fn fixed(in: []u8) *io::stream = {
let s = alloc(fixed_stream {
stream = io::stream {
@@ -34,7 +34,7 @@ export fn string(s: *io::stream) str = {
fn fixed_write(s: *io::stream, buf: const []u8) (size | io::error) = {
let stream = s: *fixed_stream;
if (len(stream.cur) == 0) {
- return 0z;
+ abort("strio::fixed buffer exceeded");
};
const n = if (len(buf) > len(stream.cur)) len(stream.cur) else len(buf);
stream.cur[..n] = buf[..n];