commit 745358a0b088a584d2ab0a20ba0e1a403b4997da
parent 3411c624b4fc926d0426ae41e65aca083faada01
Author: Byron Torres <b@torresjrjr.com>
Date: Thu, 28 Dec 2023 07:31:50 +0000
add strerror; fix write; propagate buffer errors
Diffstat:
3 files changed, 36 insertions(+), 32 deletions(-)
diff --git a/buffer.ha b/buffer.ha
@@ -1,4 +1,5 @@
use bufio;
+use encoding::utf8;
use fmt;
use io;
use strings;
@@ -42,24 +43,22 @@ fn buf_delete(buf: *Buffer, a: size, b: size) void = {
delete(buf.lines[a..b+1]);
};
-fn buf_read(buf: *Buffer, src: io::handle, a: size) (size, size) = {
+fn buf_read(buf: *Buffer, src: io::handle, a: size) ((size, size) | io::error | encoding::utf8::invalid) = {
// TODO: don't call this here, call it at a higher level
// buf_wipetrash(buf);
let ls: []*Line = [];
let sz = 0z;
for (true) {
- const bytes = match (bufio::read_line(src)) {
+ const bytes = match (bufio::read_line(src)?) {
case let bs: []u8 =>
yield bs;
case io::EOF =>
break;
- case =>
- abort();
};
sz += len(bytes) + 1; // TODO: handle newlines better
- const text = strings::fromutf8(bytes)!;
+ const text = strings::fromutf8(bytes)?;
append(ls, alloc(Line { text = text, ... }));
};
@@ -69,10 +68,10 @@ fn buf_read(buf: *Buffer, src: io::handle, a: size) (size, size) = {
return (sz, lenls);
};
-fn buf_write(buf: *Buffer, dest: io::handle, a: size, b: size) size = {
+fn buf_write(buf: *Buffer, dest: io::handle, a: size, b: size) (size | io::error) = {
let sz = 0z;
for (let n = a; n <= b; n += 1) {
- sz += fmt::fprintln(dest, buf.lines[n].text)!;
+ sz += fmt::fprintln(dest, buf.lines[n].text)?;
};
return sz;
};
diff --git a/command.ha b/command.ha
@@ -177,7 +177,7 @@ fn cmd_edit(s: *Session, cmd: *Command) (void | Error) = {
defer io::close(h)!;
buf_deleteall(&s.buf);
- const (sz, _) = buf_read(&s.buf, h, 0);
+ const (sz, _) = buf_read(&s.buf, h, 0)?;
if (!s.suppressmode) {
fmt::println(sz)!;
};
@@ -203,16 +203,16 @@ fn cmd_global_manual(s: *Session, cmd: *Command) (void | Error) = void;
fn cmd_help(s: *Session, cmd: *Command) (void | Error) = {
assert_noaddrs(s, cmd.linenums)?;
- if (s.lasterror != "") {
- fmt::println(s.lasterror)!;
+ if (s.lasterror is Error) {
+ fmt::println(strerror(s.lasterror as Error))!;
};
};
fn cmd_helpmode(s: *Session, cmd: *Command) (void | Error) = {
assert_noaddrs(s, cmd.linenums)?;
s.helpmode = !s.helpmode;
- if (s.helpmode && s.lasterror != "") {
- fmt::println(s.lasterror)!;
+ if (s.helpmode && s.lasterror is Error) {
+ fmt::println(strerror(s.lasterror as Error))!;
};
};
@@ -416,7 +416,7 @@ fn cmd_read(s: *Session, cmd: *Command) (void | Error) = {
const h = os::open(fname)?: io::handle;
defer io::close(h)!;
- const (sz, _) = buf_read(&s.buf, h, n);
+ const (sz, _) = buf_read(&s.buf, h, n)?;
if (!s.suppressmode) {
fmt::println(sz)!;
};
@@ -509,7 +509,7 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
const (a, b) = get_range(
s,
&cmd.linenums,
- addr_linenum(&s.buf, 1)!,
+ addr_linenum(&s.buf, 1)?,
addr_lastline(&s.buf),
)?;
assert_nonzero(s, a)?;
@@ -525,7 +525,7 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
};
};
- const h = match (os::open(fname)) {
+ const h = match (os::open(fname, fs::flag::WRONLY)) {
case let err: fs::error =>
yield match (err) {
case errors::noentry =>
@@ -538,7 +538,7 @@ fn cmd_write(s: *Session, cmd: *Command) (void | Error) = {
};
defer io::close(h)!;
- const sz = buf_write(&s.buf, h, a, b);
+ const sz = buf_write(&s.buf, h, a, b)?;
if (!s.suppressmode) {
fmt::println(sz)!;
};
diff --git a/main.ha b/main.ha
@@ -12,7 +12,7 @@ type Session = struct {
buf: Buffer,
mode: Mode,
helpmode: bool,
- lasterror: str,
+ lasterror: (void | Error),
suppressmode: bool,
promptmode: bool,
prompt: str,
@@ -43,6 +43,7 @@ export fn main() void = {
},
prompt = "*",
prev_shcmd = void,
+ lasterror = void,
...
};
@@ -144,29 +145,33 @@ fn exit_usage(help: []getopt::help) never = {
fn errormsg(s: *Session, err: Error) Error = {
fmt::errorln('?')!;
- const msg = match (err) {
+ let errmsg = strerror(err);
+ if (s.helpmode) {
+ fmt::errorfln(errmsg)!;
+ };
+ s.lasterror = err;
+ return err;
+};
+
+fn strerror(err: Error) str = {
+ match (err) {
case InvalidAddress =>
- yield "Invalid address";
+ return "Invalid address";
case NoFilename =>
- yield "No filename";
+ return "No filename";
case BufferModified =>
- yield "Buffer modified";
+ return "Buffer modified";
case UnexpectedAddress =>
- yield "Unexpected address";
+ return "Unexpected address";
case InvalidDestination =>
- yield "Invalid destination";
+ return "Invalid destination";
case NoMatch =>
- yield "No match";
+ return "No match";
case NoPrevShCmd =>
- yield "No previous shell command";
+ return "No previous shell command";
case let e: regex::error =>
- yield regex::strerror(e);
+ return regex::strerror(e);
case let e: fs::error =>
- yield fs::strerror(e);
- };
- s.lasterror = msg;
- if (s.helpmode) {
- fmt::errorfln(msg)!;
+ return fs::strerror(e);
};
- return err;
};