diff --git a/bulb/bulb.ha b/bulb/bulb.ha index f21b0a5..53daa10 100644 --- a/bulb/bulb.ha +++ b/bulb/bulb.ha @@ -1,8 +1,9 @@ +use bufio; use fs; use fmt; use io; -use path; use os; +use path; use strings; let bulb_path: []str = []; @@ -25,13 +26,13 @@ export fn read(output: io::handle, board: str, number: int) (void | error) = { let location = look_up_board(board)?; let file = os::open(location)?; defer io::close(file)!; - // we add 1 to acount for the blank line that will always be at the + // we add 1 to account for the blank line that will always be at the // 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(input: io::handle, board: str, user_name: (str | void)) (void | error) = { validate_board_name(board)?; let location = look_up_board(board)?; let file = os::open(location, fs::flag::APPEND | fs::flag::WRONLY)?; @@ -41,7 +42,36 @@ export fn post(board: str, user_name: (str | void), message: str) (void | error) case let user: str => yield(user); case void => yield "anonymous"; }; - fmt::fprintf(file, "{}: {}\n", user, message)?; + + static let file_wbuf: [os::BUFSZ]u8 = [0...]; + let file = bufio::init(file, [], file_wbuf); + let scanner = bufio::newscanner(input); + defer bufio::finish(&scanner); + + let saw_break = false; + fmt::fprintf(&file, "{}: ", user)?; + for (true) { + let byte = match (bufio::scan_byte(&scanner)?) { + case let byte: u8 => yield byte; + case io::EOF => break; + }; + + if (saw_break) { + fmt::fprint(&file, "\n ")?; + saw_break = false; + }; + + switch (byte) { + case '\n' => + saw_break = true; + case => + let fake_buffer: [1]u8 = [byte]; + io::write(&file, fake_buffer)?; + }; + }; + + fmt::fprint(&file, "\n")?; + bufio::flush(&file)?; }; export fn list(output: io::handle) (void | error) = { diff --git a/cmd/bulb/main.ha b/cmd/bulb/main.ha index 7e39470..e9b00dc 100644 --- a/cmd/bulb/main.ha +++ b/cmd/bulb/main.ha @@ -62,7 +62,7 @@ fn subcmd_post(cmd: *getopt::command) void = { let message = strings::join(" ", cmd.args...); defer free(message); - match (bulb::post(board, user_name, message)) { + match (bulb::post(os::stdin, board, user_name)) { case let err: bulb::error => fmt::errorf("{}: Could not read {}: {}\n", name, board, bulb::strerror(err))!; case void => void;