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:
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 \