commit f9c311ea2cf2fdd7f13a0c73940b88af8f3fe3ba
parent 876a858f8fde964dfa44490af9df8b4eb7f6559e
Author: Autumn! <autumnull@posteo.net>
Date: Tue, 9 May 2023 00:54:37 +0000
path: add peek_exts()
Signed-off-by: Autumn! <autumnull@posteo.net>
Diffstat:
1 file changed, 20 insertions(+), 8 deletions(-)
diff --git a/path/ext_stack.ha b/path/ext_stack.ha
@@ -50,19 +50,31 @@ case let s: str =>
};
// Remove and return all the extensions in a path. The result will not
-// include the leading '.', but will include separating dots. Leading dots will
-// be ignored when looking for extensions, such that ".ssh" isn't considered to
-// have any extensions. The result is borrowed from the buffer.
-export fn pop_exts(buf: *buffer) (str | void) = match (peek(buf)) {
-case void => return void;
+// include the leading '.', but will include separating dots. Leading dots
+// will be ignored when looking for extensions, such that ".ssh" isn't
+// considered to have any extensions. The result is borrowed from the buffer.
+export fn pop_exts(buf: *buffer) (str | void) = {
+ const ext = split_exts(buf);
+ buf.end = ext.0;
+ return ext.1;
+};
+
+// Examine all the extensions in a path. The result will not include the
+// leading '.', but will include separating dots. Leading dots will
+// be ignored when looking for extensions, such that ".ssh" isn't considered
+// to have any extensions. The result is borrowed from the buffer.
+export fn peek_exts(buf: *buffer) (str | void) = split_exts(buf).1;
+
+// helper function, returns (end of non-extension, extension string)
+fn split_exts(buf: *buffer) (size, (str | void)) = match (peek(buf)) {
+case void => return (buf.end, void);
case let s: str =>
const bs = strings::toutf8(s);
bs = bytes::ltrim(bs, '.');
match (bytes::index(bs, '.')) {
- case void => return void;
+ case void => return (buf.end, void);
case let i: size =>
- buf.end -= len(bs) - i;
- return strings::fromutf8_unsafe(bs[i+1..]);
+ return (buf.end - len(bs) + i, strings::fromutf8_unsafe(bs[i+1..]));
};
};