Fixed seek method of the read command

This commit is contained in:
Sasha Koshka 2024-10-09 22:27:46 -04:00
parent a2543ef78e
commit 61f85cfdda
2 changed files with 18 additions and 11 deletions

View File

@ -11,7 +11,7 @@ let bulb_path: []str = [];
export type no_such_board = !void; export type no_such_board = !void;
export type invalid_board = !void; export type invalid_board = !void;
export type error = (io::error | fs::error | no_such_board | invalid_board); export type error = !(io::error | fs::error | no_such_board | invalid_board);
export fn strerror(err: error) str = match(err) { export fn strerror(err: error) str = match(err) {
case no_such_board => return "No such board"; case no_such_board => return "No such board";
@ -20,13 +20,15 @@ case let err: fs::error => return fs::strerror(err);
case let err: io::error => return io::strerror(err); case let err: io::error => return io::strerror(err);
}; };
export fn read(board: str, number: int) (void | error) = { export fn read(output: io::handle, board: str, number: int) (void | error) = {
validate_board_name(board)?; validate_board_name(board)?;
let location = look_up_board(board)?; let location = look_up_board(board)?;
let file = os::open(location)?; let file = os::open(location)?;
defer io::close(file)!; defer io::close(file)!;
seek_to_nth_last_line(file, number)?; // we add 1 to acount for the blank line that will always be at the
io::copy(os::stdout, file)?; // bottom
seek_to_nth_last_line(file, number + 1)?;
io::copy(output, file)?;
}; };
export fn post(board: str, user_name: (str | void), message: str) (void | error) = { export fn post(board: str, user_name: (str | void), message: str) (void | error) = {
@ -42,8 +44,8 @@ export fn post(board: str, user_name: (str | void), message: str) (void | error)
fmt::fprintf(file, "{}: {}\n", user, message)?; fmt::fprintf(file, "{}: {}\n", user, message)?;
}; };
export fn list() (void | error) = { export fn list(output: io::handle) (void | error) = {
for (let directory .. bulb_path) list_boards_in(directory)?; for (let directory .. bulb_path) list_boards_in(output, directory)?;
}; };
export fn look_up_board(board: str) (str | no_such_board | invalid_board) = { export fn look_up_board(board: str) (str | no_such_board | invalid_board) = {
@ -74,11 +76,11 @@ export fn validate_board_name(board: str) (void | invalid_board) = {
}; };
}; };
fn list_boards_in(directory: str) (void | fs::error) = { fn list_boards_in(output: io:: handle, directory: str) (void | error) = {
let entries = os::readdir(directory)?; let entries = os::readdir(directory)?;
defer fs::dirents_free(entries); defer fs::dirents_free(entries);
for (let entry .. entries) { for (let entry .. entries) {
fmt::println(entry.name)!; fmt::fprintln(output, entry.name)?;
}; };
}; };
@ -108,7 +110,12 @@ fn seek_to_nth_last_line(file: io::handle, number: int) (void | io::error) = {
for (let index = len(buffer): int - 1; index >= 0; index -= 1) { for (let index = len(buffer): int - 1; index >= 0; index -= 1) {
if (buffer[index: size] == '\n') number -= 1; if (buffer[index: size] == '\n') number -= 1;
if (number <= 0) { if (number <= 0) {
io::seek(file, current + index: io::off, io::whence::SET)?; current += index;
io::seek(file, current: io::off, io::whence::SET)?;
if (current != end) {
current += 1;
io::seek(file, current, io::whence::SET)?;
};
return void; return void;
}; };
}; };

View File

@ -85,7 +85,7 @@ fn subcmd_read(cmd: *getopt::command) (void | errors::invalid) = {
}; };
}; };
match (bulb::read(board, number)) { match (bulb::read(os::stdout, board, number)) {
case let err: bulb::error => case let err: bulb::error =>
fmt::errorf("{}: Could not read {}: {}\n", name, board, bulb::strerror(err))!; fmt::errorf("{}: Could not read {}: {}\n", name, board, bulb::strerror(err))!;
case void => void; case void => void;
@ -93,7 +93,7 @@ fn subcmd_read(cmd: *getopt::command) (void | errors::invalid) = {
}; };
fn subcmd_ls(cmd: *getopt::command) void = { fn subcmd_ls(cmd: *getopt::command) void = {
match (bulb::list()) { match (bulb::list(os::stdout)) {
case let err: bulb::error => case let err: bulb::error =>
fmt::errorf("{}: Could not list boards: {}\n", name, bulb::strerror(err))!; fmt::errorf("{}: Could not list boards: {}\n", name, bulb::strerror(err))!;
case void => void; case void => void;