hare

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

commit 45965b48675c1cf9d22f77d9db717fb4187e98fb
parent dd3540c094cd491be69195524149cf6605bc4d0e
Author: Autumn! <autumnull@posteo.net>
Date:   Sun,  7 May 2023 01:43:30 +0000

path: make iterators only take a *buffer

Signed-off-by: Autumn! <autumnull@posteo.net>

Diffstat:
Mfs/util.ha | 16+++++++++-------
Mpath/buffer.ha | 12++++++++++++
Mpath/iter.ha | 21+++++++++++----------
Mpath/names.ha | 10+++++-----
Dpath/util.ha | 29-----------------------------
Mscripts/gen-stdlib | 1-
Mstdlib.mk | 2--
7 files changed, 37 insertions(+), 54 deletions(-)

diff --git a/fs/util.ha b/fs/util.ha @@ -143,9 +143,11 @@ fn rmdirall_path(fs: *fs, buf: *path::buffer) (void | error) = { // collapsing any "." or ".." path components. The return value is statically // allocated and will be overwritten on subsequent calls. export fn realpath(fs: *fs, path: str) (str | error) = { - static let buf = path::buffer { ... }; - path::set(&buf)!; - const iter = path::iter(path); + static let res = path::buffer { ... }; + path::set(&res)!; + static let pathbuf = path::buffer { ... }; + path::set(&pathbuf, path)!; + const iter = path::iter(&pathbuf); for (true) { const item = match (path::next(&iter)) { case let item: str => @@ -154,7 +156,7 @@ export fn realpath(fs: *fs, path: str) (str | error) = { break; }; - const item = path::push(&buf, item)!; + const item = path::push(&res, item)!; const link = match (readlink(fs, item)) { case let link: str => yield link; @@ -165,11 +167,11 @@ export fn realpath(fs: *fs, path: str) (str | error) = { }; if (!path::abs(link)) { - path::push(&buf, "..", link)!; + path::push(&res, "..", link)!; } else { - path::set(&buf, link)!; + path::set(&res, link)!; }; }; - return path::string(&buf); + return path::string(&res); }; diff --git a/path/buffer.ha b/path/buffer.ha @@ -30,3 +30,15 @@ export fn string(buf: *buffer) str = { if (buf.end == 0) return "."; return strings::fromutf8_unsafe(buf.buf[..buf.end]); }; + +// Check if a path is an absolute path. +export fn abs(path: (*buffer | str)) bool = match (path) { +case let path: str => return strings::hasprefix(path, pathsepstr); +case let buf: *buffer => return 0 < buf.end && buf.buf[0] == PATHSEP; +}; + +// Check if a path is the root directory. +export fn isroot(path: (*buffer | str)) bool = match (path) { +case let path: str => return path == pathsepstr; +case let buf: *buffer => return buf.end == 1 && buf.buf[0] == PATHSEP; +}; diff --git a/path/iter.ha b/path/iter.ha @@ -19,8 +19,8 @@ let pathsep: []u8 = [PATHSEP]; // Returns an iterator which yields each component of a path. If the path is // absolute, the first component will be the root path (e.g. "/"). -export fn iter(path: (str | *buffer)) iterator = { - let path = getbytes(path); +export fn iter(buf: *buffer) iterator = { + let path = buf.buf[..buf.end]; let flags = iflags::NONE; if (len(path) > 0 && path[0] == PATHSEP) { flags |= iflags::ABSOLUTE; @@ -51,27 +51,28 @@ export fn next(iter: *iterator) (str | void) = { }; @test fn iter() void = { - const s = strings::join(pathsepstr, "", "foo", "bar", "baz"); - let i = iter(s); + const buf = init(pathsepstr, "foo", "bar", "baz")!; + let i = iter(&buf); assert(next(&i) as str == pathsepstr); assert(next(&i) as str == "foo"); assert(next(&i) as str == "bar"); assert(next(&i) as str == "baz"); assert(next(&i) is void); - free(s); - const s = strings::join(pathsepstr, "foo", "bar", "baz", ""); - let i = iter(s); + set(&buf, "foo", "bar", "baz")!; + let i = iter(&buf); assert(next(&i) as str == "foo"); assert(next(&i) as str == "bar"); assert(next(&i) as str == "baz"); assert(next(&i) is void); - let i = iter("foo"); + + set(&buf, "foo")!; + let i = iter(&buf); assert(next(&i) as str == "foo"); assert(next(&i) is void); - free(s); - let i = iter(pathsepstr); + set(&buf, pathsepstr)!; + let i = iter(&buf); assert(next(&i) as str == pathsepstr); assert(next(&i) is void); }; diff --git a/path/names.ha b/path/names.ha @@ -13,8 +13,8 @@ use strings; // extension("foo/example") => ("example", "") // extension("foo/example.txt") => ("example", ".txt") // extension("foo/example.tar.gz") => ("example.tar", ".gz") -export fn extension(p: (str | *buffer)) (str, str) = { - let p = getstring(p); +// this change is only here until the next commit, rebase is annoying +export fn extension(p: str) (str, str) = { if (p == "") { return ("", ""); }; @@ -48,7 +48,7 @@ export fn extension(p: (str | *buffer)) (str, str) = { }; fn assertpatheql( - func: *fn(path: (str | *buffer)) const str, + func: *fn(path: str) const str, expected: str, path: str... ) void = { @@ -57,5 +57,5 @@ fn assertpatheql( free(s); }; -fn ext0(p: (str | *buffer)) const str = extension(p).0; -fn ext1(p: (str | *buffer)) const str = extension(p).1; +fn ext0(p: str) const str = extension(p).0; +fn ext1(p: str) const str = extension(p).1; diff --git a/path/util.ha b/path/util.ha @@ -1,29 +0,0 @@ -// License: MPL-2.0 -// (c) 2021-2022 Drew DeVault <sir@cmpwn.com> -use strings; - -fn getbytes(in: (str | *buffer)) []u8 = { - match (in) { - case let st: str => - return strings::toutf8(st); - case let buf: *buffer => - return buf.buf[..buf.end]; - }; -}; - -fn getstring(in: (str | *buffer)) str = { - match (in) { - case let st: str => - return st; - case let buf: *buffer => - return string(buf); - }; -}; - -// Returns true if a path is an absolute path. -export fn abs(path: (*buffer | str)) bool = { - let path = getbytes(path); - return 0 < len(path) && path[0] == PATHSEP; -}; - -export fn isroot(buf: *buffer) bool = buf.end == 1 && buf.buf[0] == PATHSEP; diff --git a/scripts/gen-stdlib b/scripts/gen-stdlib @@ -1204,7 +1204,6 @@ path() { '+$(PLATFORM).ha' \ buffer.ha \ error.ha \ - util.ha \ stack.ha \ names.ha \ posix.ha \ diff --git a/stdlib.mk b/stdlib.mk @@ -1837,7 +1837,6 @@ stdlib_path_any_srcs = \ $(STDLIB)/path/+$(PLATFORM).ha \ $(STDLIB)/path/buffer.ha \ $(STDLIB)/path/error.ha \ - $(STDLIB)/path/util.ha \ $(STDLIB)/path/stack.ha \ $(STDLIB)/path/names.ha \ $(STDLIB)/path/posix.ha \ @@ -4113,7 +4112,6 @@ testlib_path_any_srcs = \ $(STDLIB)/path/+$(PLATFORM).ha \ $(STDLIB)/path/buffer.ha \ $(STDLIB)/path/error.ha \ - $(STDLIB)/path/util.ha \ $(STDLIB)/path/stack.ha \ $(STDLIB)/path/names.ha \ $(STDLIB)/path/posix.ha \