path+x86_64 +linux

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:

Assuming that SEP is '/', "/usr//bin/../bin/./hare/" becomes "/usr/bin/hare" and "../../foo/bar" is unchanged.

Different fs::fs implementations may have different rules for normalizing paths. For use-cases in which this is relevant, fs::resolve should be used instead.

The buffer object includes an array of length MAX, which can be somewhat large; on Linux it's 4095 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

// Undocumented types:
type buffer = struct {
	buf: [MAX]u8,
	end: size,
};
type iterator = struct {
	cur: []u8,
	reverse: bool,
};

Errors

type cant_extend = !void;
type error = !(cant_extend | too_long | not_prefix);
type not_prefix = !void;
type too_long = !void;

Constants

def MAX: size = 4095;
def SEP: u8 = '/';

Functions

fn abs(path: (*buffer | str)) bool;
fn basename(path: const str) const str;
fn dirname(path: const str) const str;
fn init(items: str...) (buffer | error);
fn isroot(path: (*buffer | str)) bool;
fn iter(buf: *buffer) iterator;
fn iterrem(it: *iterator) str;
fn local(path: str) str;
fn nextiter(it: *iterator) (str | done);
fn parent(buf: *const buffer) (str | error);
fn peek(buf: *const buffer) (str | void);
fn peek_ext(buf: *buffer) (str | void);
fn peek_exts(buf: *buffer) (str | void);
fn peekiter(it: *iterator) (str | void);
fn pop(buf: *buffer) (str | void);
fn pop_ext(buf: *buffer) (str | void);
fn pop_exts(buf: *buffer) (str | void);
fn popprefix(buf: *buffer, prefix: str) (str | error);
fn prepend(buf: *buffer, prefix: str...) (str | error);
fn push(buf: *buffer, items: str...) (str | error);
fn push_ext(buf: *buffer, exts: str...) (str | error);
fn riter(buf: *buffer) iterator;
fn set(buf: *buffer, items: str...) (str | error);
fn strerror(e: error) str;
fn string(buf: *buffer) str;
fn trimprefix(buf: *buffer, prefix: str) (str | error);

Types

type buffer[link]

Show undocumented member
type buffer = struct {
	buf: [MAX]u8,
	end: size,
};

type iterator[link]

Show undocumented member
type iterator = struct {
	cur: []u8,
	reverse: bool,
};

Errors

type cant_extend[link]

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[link]

type error = !(cant_extend | too_long | not_prefix);

Represents an error during a path manipulation

type not_prefix[link]

type not_prefix = !void;

Returned when trimprefix receives a prefix that is not present.

type too_long[link]

type too_long = !void;

Returned when a path buffer would have overflowed.

Constants

def MAX[link]

def MAX: size = 4095;

Maximum length of a file path for this platform.

def SEP[link]

def SEP: u8 = '/';

Platform-specific path separator byte.

Functions

fn abs[link]

fn abs(path: (*buffer | str)) bool;

Check if a path is an absolute path.

fn basename[link]

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[link]

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[link]

fn init(items: str...) (buffer | error);

Initializes a new path buffer.

fn isroot[link]

fn isroot(path: (*buffer | str)) bool;

Check if a path is the root directory.

fn iter[link]

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[link]

fn iterrem(it: *iterator) str;

Gets the remaining path from an iterator, without advancing the iterator.

fn local[link]

fn local(path: str) str;

Replaces all instances of '/' in a string with SEP. The result is statically-allocated.

fn nextiter[link]

fn nextiter(it: *iterator) (str | done);

Returns the next path component from an iterator, or done if none remain. Advances the iterator.

fn parent[link]

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[link]

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[link]

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[link]

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[link]

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[link]

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[link]

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[link]

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[link]

fn popprefix(buf: *buffer, prefix: str) (str | error);

Equivalent to trimprefix, but modifies the buffer in the process.

fn prepend[link]

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[link]

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[link]

fn push_ext(buf: *buffer, exts: 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[link]

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[link]

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[link]

fn strerror(e: error) str;

Convert an error into a descriptive string.

fn string[link]

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[link]

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 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.