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.
let buf = path::init();
path::add(&buf, "/", "foo", "bar", "baz.txt")!;
fmt::println(path::string(&buf))!; // "/foo/bar/baz.txt"
path::add(&buf, "../.././hello.txt")!;
fmt::println(path::string(&buf))!; // "/foo/hello.txt"
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.
// Stack allocated
let buf = path::init();
// Statically allocated
static let buf = path::buffer { ... };
path::reset(&buf);
// Heap allocated
let buf = alloc(path::init());
defer free(buf);
Index
Types
type buffer;
type iflags;
type iterator;
Constants
const PATHSEP: u8;
const PATH_MAX: size;
Functions
fn abs(str) bool;
fn add(*buffer, str...) (str | errors::overflow);
fn allocate(*buffer) str;
fn basename((str | *buffer)) const str;
fn dirname((str | *buffer)) const str;
fn extension((str | *buffer)) (str, str);
fn init() buffer;
fn iter((str | *buffer)) iterator;
fn join(str...) str;
fn next(*iterator) (str | void);
fn reset(*buffer) void;
fn set(*buffer, str...) (str | errors::overflow);
fn string(*buffer) str;
Types
type buffer
Show undocumented member
type buffer = struct {
buf: [PATH_MAX]u8,
end: size,
};
type iflags
Show undocumented member
type iflags = enum uint {
NONE = 0,
ABSOLUTE = 1 << 0,
};
type iterator
Show undocumented member
type iterator = struct {
tok: bytes::tokenizer,
flags: iflags,
};
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: str) bool;
Returns true if a path is an absolute path.
fn add
fn add(buf: *buffer, items: str...) (str | errors::overflow);
Joins several path elements together and copies them into a path buffer.
Returns the new string value of the path.
fn allocate
fn allocate(buf: *buffer) str;
Like string but the return value is copied to the heap and must be freed
by the caller.
fn basename
fn basename(path: (str | *buffer)) const 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. If the path consists solely of the target's path separator, a string of
the path is returned unmodified. If the path is empty, "." is returned. The
return value is either borrowed from the input or statically allocated; use
strings::dup to extend its lifetime or modify it.
fn dirname
fn dirname(path: (str | *buffer)) const str;
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. If the path consists solely of
the target's path separator, a string to the path is returned unmodified. If
the path is empty, "." is returned. The return value is either borrowed from
the input or statically allocated; use strings::dup to extend its
lifetime or modify it.
fn extension
fn extension(p: (str | *buffer)) (str, str);
Returns the file name and extension for a path. The return value is borrowed
from the input, see strings::dup to extend its lifetime.
The extension includes the '.' character.
extension("foo/example") => ("example", "")
extension("foo/example.txt") => ("example", ".txt")
extension("foo/example.tar.gz") => ("example.tar", ".gz")
fn init
fn init() buffer;
Initializes a new path buffer.
fn iter
fn iter(path: (str | *buffer)) iterator;
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. "/").
fn join
fn join(items: str...) str;
Joins a list of path components together, normalizes it, and returns the
resulting string. The caller must free the return value. If the resulting
path would exceed PATH_MAX, the program aborts.
fn next
fn next(iter: *iterator) (str | void);
Returns the next path component from an iterator, or void if none remain.
fn reset
fn reset(buf: *buffer) void;
Resets a path buffer to its initial state.
fn set
fn set(buf: *buffer, items: str...) (str | errors::overflow);
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 string
fn string(buf: *buffer) str;
Returns the current path stored in this buffer. 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 path will only end in a
slash if the last item which was added ended in PATHSEP, like so:
let buf = path::init();
path::set(&buf, "foo", "bar")!;
assert(path::string(&buf) == "foo/bar");
path::set(&buf, "foo", "bar/")!;
assert(path::string(&buf) == "foo/bar/");
path::set(&buf, "foo", "bar", "/")!;
assert(path::string(&buf) == "foo/bar/");
The return value is borrowed from the buffer. Use allocate to extend the
lifetime of the string.