hare

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

commit 6e56868c2a71bd7aece81349f3fe5ec4271dc61c
parent 398e4c23008c4a1f3ac90be31f1c0727984d053f
Author: Drew DeVault <sir@cmpwn.com>
Date:   Sat, 27 Feb 2021 09:50:23 -0500

path: add basename, dirname

Diffstat:
Apath/names.ha | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Apath/norm.ha | 6++++++
2 files changed, 58 insertions(+), 0 deletions(-)

diff --git a/path/names.ha b/path/names.ha @@ -0,0 +1,52 @@ +use bytes; +use strings; +use io; + +// Returns the directory name for a given path. For a path to a file name, this +// returns the directory in which that file resides. For a path to a directory, +// this returns the path to its parent directory. The return value is borrowed +// from the input, use [dup] to extend its lifetime. +export fn dirname(path: path::path) path::path = { + let b = pathbytes(normalize(path)); + let i = bytes::rindex(b, PATHSEP) as size; + if (i == 0) { + b = [PATHSEP]; + i += 1; + }; + return + if (path is str) strings::from_utf8_unsafe(b[..i]) + else b[..i]; +}; + +@test fn dirname() void = { + let p: path = "/foo/bar"; + assert(dirname(p) as str == "/foo"); + let p: path = "/foo"; + assert(dirname(p) as str == "/"); + let p: path = "/"; + assert(dirname(p) as str == "/"); +}; + +// Returns the final component of a given path. For a path to a file name, this +// returns the file name. For a path to a directory, this returns the directory +// name. The return value is borrowed from the input, use [dup] to extend its +// lifetime. +export fn basename(path: path::path) path::path = { + let b = pathbytes(normalize(path)); + let i = if (len(b) == 1) { + b = [PATHSEP]; + 0z; + } else bytes::rindex(b, PATHSEP) as size + 1; + return + if (path is str) strings::from_utf8_unsafe(b[i..]) + else b[i..]; +}; + +@test fn basename() void = { + let p: path = "/foo/bar"; + assert(basename(p) as str == "bar"); + let p: path = "/foo"; + assert(basename(p) as str == "foo"); + let p: path = "/"; + assert(basename(p) as str == "/"); +}; diff --git a/path/norm.ha b/path/norm.ha @@ -0,0 +1,6 @@ +// Normalizes a path, merging successive path separators, and resolving . and .. +// components. Modifies the path in-place and returns the same object. +export fn normalize(p: path::path) path::path = { + // TODO + return p; +};