commit 4f459aee76753804e7a0c814f42ddc2485de6766
parent 473d4e15bf2c40b9b7e703a1bbe5408ba04dfece
Author: Byron Torres <b@torresjrjr.com>
Date: Sun, 12 Sep 2021 16:06:51 +0100
Add buf_insert(), fix buf_read()
Diffstat:
M | buffer.ha | | | 51 | ++++++++++++++++++++++++++++++++++++++++++++++----- |
M | command.ha | | | 38 | ++++++++++++++++++-------------------- |
M | ed.ha | | | 3 | ++- |
3 files changed, 66 insertions(+), 26 deletions(-)
diff --git a/buffer.ha b/buffer.ha
@@ -1,11 +1,18 @@
use bufio;
use fmt;
+
type buffer = struct {
+ cur: cursor,
head: *linenode,
tail: *linenode,
};
+type cursor = struct {
+ num: uint,
+ node: *linenode,
+};
+
type linenode = struct {
value: value,
prev: *linenode,
@@ -18,12 +25,15 @@ type headnode = void;
type tailnode = void;
+
// Initialises a new buffer.
fn new_buffer() *buffer = {
const head = alloc(linenode { value = headnode, ... });
const tail = alloc(linenode { value = tailnode, prev = head });
head.next = tail;
+ const cur = cursor { num = 0, node = head };
return alloc(buffer {
+ cur = cur,
head = head,
tail = tail,
});
@@ -31,10 +41,12 @@ fn new_buffer() *buffer = {
// Reads text from *io::stream, writes to a buffer.
// Buffer should be empty, otherwise, existing linenodes will be leaked.
+// TODO: Clear buffer before reading?
fn buf_read(buf: *buffer, source: *io::stream) size = {
- let localhead = buf.head;
+ const localhead = buf.head;
const localtail = buf.tail;
+ let prevnode = localhead;
let n = 0z;
for (true) {
@@ -43,21 +55,23 @@ fn buf_read(buf: *buffer, source: *io::stream) size = {
io::EOF => break,
rawline: []u8 => rawline,
};
+ // TODO: make sure to free lines later
//defer free(rawline);
- n += len(rawline);
+
+ n += len(rawline) + 1;
const value = fmt::bsprint(rawline);
const ln = alloc(linenode {
value = value,
- prev = localhead,
+ prev = prevnode,
next = localtail,
});
- localhead.next = ln;
+ prevnode.next = ln;
localtail.prev = ln;
- localhead = ln;
+ prevnode = ln;
};
return n;
@@ -67,6 +81,7 @@ fn buf_read(buf: *buffer, source: *io::stream) size = {
fn buf_write(buf: *buffer, dest: *io::stream) size = {
let ln = buf.head;
let n = 0z;
+
for (true) {
match (ln.value) {
headnode => {
@@ -82,3 +97,29 @@ fn buf_write(buf: *buffer, dest: *io::stream) size = {
return n;
};
+// Inserts the contents of b into buf where buf.cur points at.
+fn buf_insert(buf: *buffer, b: *buffer) void = {
+ const localhead = buf.cur.node;
+ const localtail = localhead.next;
+
+ let prevnode = localhead;
+ let ln = b.head;
+
+ for (true) {
+ match (ln.value) {
+ headnode => {
+ ln = ln.next;
+ },
+ text: str => {
+ ln.prev = prevnode;
+
+ prevnode.next = ln;
+ localtail.prev = ln;
+
+ prevnode = ln;
+ ln = ln.next;
+ },
+ tailnode => break
+ };
+ };
+};
diff --git a/command.ha b/command.ha
@@ -4,18 +4,17 @@ use fs;
// 'e' command
fn cmd_edit(buf: *buffer, fname: filename) void = {
- match (fname) {
- void => void,
+ const n = match (fname) {
+ void => abort("TODO"),
fname: str => match (os::open(fname)) {
err: fs::error => fmt::fatal("Error {}", fs::strerror(err)),
- f: io::file => {
- const n = buf_read(buf, &f);
- if (!surpress) {
- fmt::println(n)?;
- };
- },
+ f: io::file => buf_read(buf, &f),
},
};
+
+ if (!surpress) {
+ fmt::println(n)?;
+ };
};
// 'w' command
@@ -32,9 +31,9 @@ fn cmd_write(buf: *buffer, fname: filename) void = {
fname: str => match (os::open(fname, flags...)) {
fs::error => match (os::create(fname, mode)) {
err: fs::error => fmt::fatal("Error {}", fs::strerror(err)),
- file: io::file => file,
+ f: io::file => f,
},
- file: io::file => file,
+ f: io::file => f,
},
};
@@ -48,19 +47,18 @@ fn cmd_write(buf: *buffer, fname: filename) void = {
// 'r' command
fn cmd_read(buf: *buffer, fname: filename) void = {
const scratch = new_buffer();
- match (fname) {
- void => void,
+ const n = match (fname) {
+ void => abort("TODO"),
fname: str => match (os::open(fname)) {
err: fs::error => fmt::fatal("Error {}", fs::strerror(err)),
- f: io::file => {
- const n = buf_read(scratch, &f);
- if (!surpress) {
- fmt::println(n)?;
- };
- },
+ f: io::file => buf_read(scratch, &f),
},
};
- // TODO: Insert scratch into buf appropriately.
- // deps: buf_insert()
+
+ buf_insert(buf, scratch);
+
+ if (!surpress) {
+ fmt::println(n)?;
+ };
};
diff --git a/ed.ha b/ed.ha
@@ -65,13 +65,14 @@ export fn main() void = {
cmd_edit(buf, fname);
print_buffer(buf);
- cmd_read(buf, "./tmp/gpl.txt");
+ cmd_read(buf, "./tmp/li.txt");
print_buffer(buf);
cmd_write(buf, "./tmp/out");
print_buffer(buf);
};
+// TODO
// "3,7,/a/,+2m4"
// str -> struct {
// prefix_ranges: []addr, // "2" "+2" "-1"