path
The path module provides utilities for working with filesystem paths.
Note that Hare expects paths to be valid UTF-8 strings. If you require the use
of non-UTF-8 paths (ideally for only as long as it takes to delete or rename
those files), see the low-level functions available from rt.
Use of the buffer type is recommended for efficient and consistent
manipulation of filesystem paths. The path will always be
normalized, which is to say that it will not include any of the following:
- Redundant ".." components
- Redundant path separators
- Any "." components, except in the case of "."
Assuming that PATHSEP is '/', "/usr//bin/../bin/./hare/" becomes
"/usr/bin/hare" and "../../foo/bar" is unchanged.
The buffer object includes an array of length PATH_MAX, which can be
somewhat large; on Linux it's 4096 bytes. You can allocate this on the stack in
most cases, but you may prefer to allocate it elsewhere depending on your
needs. Functions in this module return too_long if the buffer's capacity
would be exceeded.
// Stack allocated
let buf = path::init()!;
// Statically allocated
static let buf = path::buffer { ... };
path::set(&buf)!;
// Heap allocated
let buf = alloc(path::init()!);
defer free(buf);
Index
Types
type buffer;
type iterator;
Errors
type cant_extend;
type error;
type not_prefix;
type too_long;
Constants
const PATHSEP: u8;
const PATH_MAX: size;
Functions
fn abs((*buffer | str)) bool;
fn basename(const str) const str;
fn dirname(const str) const str;
fn init(str...) (buffer | error);
fn isroot((*buffer | str)) bool;
fn iter(*buffer) iterator;
fn iterrem(*iterator) str;
fn local(str) str;
fn nextiter(*iterator) (str | void);
fn parent(*const buffer) (str | error);
fn peek(*const buffer) (str | void);
fn peek_ext(*buffer) (str | void);
fn peek_exts(*buffer) (str | void);
fn peekiter(*iterator) (str | void);
fn pop(*buffer) (str | void);
fn pop_ext(*buffer) (str | void);
fn pop_exts(*buffer) (str | void);
fn popprefix(*buffer, str) (str | error);
fn prepend(*buffer, str...) (str | error);
fn push(*buffer, str...) (str | error);
fn push_ext(*buffer, str...) (str | error);
fn riter(*buffer) iterator;
fn set(*buffer, str...) (str | error);
fn strerror(error) str;
fn string(*buffer) str;
fn trimprefix(*buffer, str) (str | error);
Types
type buffer
Show undocumented member
type buffer = struct {
buf: [PATH_MAX]u8,
end: size,
};
type iterator
Show undocumented member
type iterator = struct {
cur: []u8,
reverse: bool,
};
Errors
type cant_extend
type cant_extend = !void;
Returned when adding an extension if the path is root, or the final path
segment consists entirely of dots.
type error
type error = !(cant_extend | too_long | not_prefix);
Represents an error during a path manipulation
type not_prefix
type not_prefix = !void;
Returned when trimprefix receives a prefix that is not present.
type too_long
type too_long = !void;
Returned when a path buffer would have overflowed.
Constants
def PATHSEP
def PATHSEP: u8;
Platform-specific path separator byte.
def PATH_MAX
def PATH_MAX: size;
Maximum length of a file path for this platform.
Functions
fn abs
fn abs(path: (*buffer | str)) bool;
Check if a path is an absolute path.
fn basename
fn basename(path: const str) const str;
A POSIX-compliant implementation of basename. See the POSIX specification
for more information. Note that this function does *not* normalize the
input. The return value is either borrowed from the input or statically
allocated; use strings::dup to extend its lifetime.
fn dirname
fn dirname(path: const str) const str;
A POSIX-compliant implementation of dirname. See the POSIX specification
for more information. Note that this function does *not* normalize the
input. The return value is either borrowed from the input or statically
allocated; use strings::dup to extend its lifetime.
fn init
fn init(items: str...) (buffer | error);
Initializes a new path buffer.
fn isroot
fn isroot(path: (*buffer | str)) bool;
Check if a path is the root directory.
fn iter
fn iter(buf: *buffer) iterator;
Returns an iterator which yields each component of a path, moving down
through child dirs. If the path is absolute, the first component will be
the root. The iterator can be copied to save its state.
fn iterrem
fn iterrem(it: *iterator) str;
get the remaining path from an iterator, without advancing the iterator.
fn local
fn local(path: str) str;
Replace '/' with system-dependent path separator in a string. Modifies the
original string, but is idempotent. The result is borrowed from the input.
fn nextiter
fn nextiter(it: *iterator) (str | void);
Returns the next path component from an iterator, or void if none
remain. Advances the iterator.
fn parent
fn parent(buf: *const buffer) (str | error);
Returns the parent directory for a given path, without modifying the buffer.
If the path is the root directory, the root directory is returned. The value
is either borrowed from the input or statically allocated; use
strings::dup to extend its lifetime or modify it.
fn peek
fn peek(buf: *const buffer) (str | void);
Examine the final path segment in a buffer.
Returns void if the path is empty or is the root dir.
fn peek_ext
fn peek_ext(buf: *buffer) (str | void);
Examine the final extension in a path. The result will not
include the leading '.'. The result is borrowed from the buffer. Leading dots
will be ignored when looking for extensions, such that ".ssh" isn't
considered to have any extensions.
fn peek_exts
fn peek_exts(buf: *buffer) (str | void);
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.
fn peekiter
fn peekiter(it: *iterator) (str | void);
Returns the next path component from an iterator, or void if none
remain. Does not advance the iterator.
fn pop
fn pop(buf: *buffer) (str | void);
Remove and return the final path segment in a buffer.
Returns void if the path is empty or is the root dir.
fn pop_ext
fn pop_ext(buf: *buffer) (str | void);
Remove and return the final extension in a path. The result will not
include the leading '.'. The result is borrowed from the buffer. Leading dots
will be ignored when looking for extensions, such that ".ssh" isn't
considered to have any extensions.
fn pop_exts
fn pop_exts(buf: *buffer) (str | void);
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.
fn popprefix
fn popprefix(buf: *buffer, prefix: str) (str | error);
Equivalent to trimprefix, but modifies the buffer in the process.
fn prepend
fn prepend(buf: *buffer, prefix: str...) (str | error);
Add a prefix to a buffer. The buffer will be modified, and it will
remain normalized, so any ".." components in the original buffer may be
collapsed.
fn push
fn push(buf: *buffer, items: str...) (str | error);
Appends path elements onto the end of a path buffer.
Returns the new string value of the path.
fn push_ext
fn push_ext(buf: *buffer, ext: str...) (str | error);
Add extensions onto the end of the final path segment. The separating '.'
will be inserted for you. If the final path segment consists entirely of dots
or the path is root, this function will return cant_extend.
fn riter
fn riter(buf: *buffer) iterator;
Returns an iterator which yields each component of a path, moving up
through parent dirs. If the path is absolute, the last component will be
the root. The iterator can be copied to save its state.
fn set
fn set(buf: *buffer, items: str...) (str | error);
Sets the value of a path buffer to a list of components, overwriting any
previous value. Returns the new string value of the path.
fn strerror
fn strerror(e: error) str;
Convert an error into a descriptive string.
fn string
fn string(buf: *buffer) str;
Returns the current path stored in this buffer.
The return value is borrowed from the buffer. Use strings::dup to
extend the lifetime of the string.
fn trimprefix
fn trimprefix(buf: *buffer, prefix: str) (str | error);
Returns a buffer without a prefix. The prefix is normalized before
processing, and this function will return too_long if the prefix is
longer than PATH_MAX. If the prefix is not present, returns
not_prefix. The resulting path will always be relative.
This function does not modify the buffer. See popprefix.