hare

The Hare programming language
git clone https://git.torresjrjr.com/hare.git
Log | Files | Refs | README | LICENSE

commit 45f249f3ad1c40ad254c3fd026187744acaa4b99
parent e15652b32701ef43535fe018f05ebf6f3718ecfc
Author: Drew DeVault <sir@cmpwn.com>
Date:   Wed, 24 Feb 2021 12:39:00 -0500

fs: implement mode_str

Diffstat:
Mfs/util.ha | 41++++++++++++++++++++++++++++++++++++++---
1 file changed, 38 insertions(+), 3 deletions(-)

diff --git a/fs/util.ha b/fs/util.ha @@ -1,4 +1,6 @@ +use fmt; use io; +use strio; // Returns a human-friendly representation of an error. export fn errstr(err: error) const str = match (err) { @@ -7,10 +9,43 @@ export fn errstr(err: error) const str = match (err) { err: io::error => io::errstr(err), }; -// Converts a mode into a Unix-like mode string (e.g. "-rw-r--r--") +// Converts a mode into a Unix-like mode string (e.g. "-rw-r--r--"). The string +// is statically allocated, use [strings::dup] to duplicate it or it will be +// overwritten on subsequent calls. export fn mode_str(m: mode) const str = { - // TODO: blocked on bufio::fixed - abort(); + // TODO: This could be more efficient without fmt + static let buf: [11]u8 = [0...]; + let sink = strio::fixed(buf); + fmt::fprintf(sink, "{}{}{}{}{}{}{}{}{}{}", + if (m & mode::DIR == mode::DIR) "d" + else if (m & mode::FIFO == mode::FIFO) "p" + else if (m & mode::SOCK == mode::SOCK) "s" + else "-", + if (m & mode::USER_R == mode::USER_R) "r" else "-", + if (m & mode::USER_W == mode::USER_W) "w" else "-", + if (m & mode::SETUID == mode::SETUID) "s" + else if (m & mode::USER_X == mode::USER_X) "x" + else "-", + if (m & mode::GROUP_R == mode::GROUP_R) "r" else "-", + if (m & mode::GROUP_W == mode::GROUP_W) "w" else "-", + if (m & mode::SETGID == mode::SETGID) "s" + else if (m & mode::GROUP_X == mode::GROUP_X) "x" + else "-", + if (m & mode::OTHER_R == mode::OTHER_R) "r" else "-", + if (m & mode::OTHER_W == mode::OTHER_W) "w" else "-", + if (m & mode::STICKY == mode::STICKY) "t" + else if (m & mode::OTHER_X == mode::OTHER_X) "x" + else "-", + ); + return strio::string(sink); +}; + +@test fn mode_str() void = { + assert(mode_str(0o777: mode) == "-rwxrwxrwx"); + assert(mode_str(mode::DIR | 0o755: mode) == "drwxr-xr-x"); + assert(mode_str(0o755: mode | mode::SETUID) == "-rwsr-xr-x"); + assert(mode_str(0o644: mode) == "-rw-r--r--"); + assert(mode_str(0: mode) == "----------"); }; // Returns the permission bits of a file mode.