ed

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README

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:
Mbuffer.ha | 51++++++++++++++++++++++++++++++++++++++++++++++-----
Mcommand.ha | 38++++++++++++++++++--------------------
Med.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"