structstd.Build.Cache.Path[src]

Fields

root_dir: Cache.Directory
sub_path: []const u8 = ""

The path, relative to the root dir, that this Path represents. Empty string means the root_dir is the path.

Functions

Functionclone[src]

pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path

Parameters

p: Path
arena: Allocator

Source Code

Source code
pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path {
    return .{
        .root_dir = try p.root_dir.clone(arena),
        .sub_path = try arena.dupe(u8, p.sub_path),
    };
}

Functioncwd[src]

pub fn cwd() Path

Source Code

Source code
pub fn cwd() Path {
    return initCwd("");
}

FunctioninitCwd[src]

pub fn initCwd(sub_path: []const u8) Path

Parameters

sub_path: []const u8

Source Code

Source code
pub fn initCwd(sub_path: []const u8) Path {
    return .{ .root_dir = Cache.Directory.cwd(), .sub_path = sub_path };
}

Functionjoin[src]

pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path

Parameters

p: Path
arena: Allocator
sub_path: []const u8

Source Code

Source code
pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
    if (sub_path.len == 0) return p;
    const parts: []const []const u8 =
        if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
    return .{
        .root_dir = p.root_dir,
        .sub_path = try fs.path.join(arena, parts),
    };
}

FunctionresolvePosix[src]

pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path

Parameters

p: Path
arena: Allocator
sub_path: []const u8

Source Code

Source code
pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
    if (sub_path.len == 0) return p;
    return .{
        .root_dir = p.root_dir,
        .sub_path = try fs.path.resolvePosix(arena, &.{ p.sub_path, sub_path }),
    };
}

FunctionjoinString[src]

pub fn joinString(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Error![]u8

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn joinString(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Error![]u8 {
    const parts: []const []const u8 =
        if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
    return p.root_dir.join(gpa, parts);
}

FunctionjoinStringZ[src]

pub fn joinStringZ(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Error![:0]u8

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn joinStringZ(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Error![:0]u8 {
    const parts: []const []const u8 =
        if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
    return p.root_dir.joinZ(gpa, parts);
}

FunctionopenFile[src]

pub fn openFile( p: Path, sub_path: []const u8, flags: fs.File.OpenFlags, ) !fs.File

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn openFile(
    p: Path,
    sub_path: []const u8,
    flags: fs.File.OpenFlags,
) !fs.File {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.openFile(joined_path, flags);
}

FunctionopenDir[src]

pub fn openDir( p: Path, sub_path: []const u8, args: fs.Dir.OpenOptions, ) fs.Dir.OpenError!fs.Dir

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn openDir(
    p: Path,
    sub_path: []const u8,
    args: fs.Dir.OpenOptions,
) fs.Dir.OpenError!fs.Dir {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.openDir(joined_path, args);
}

FunctionmakeOpenPath[src]

pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.Dir.OpenOptions) !fs.Dir

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.Dir.OpenOptions) !fs.Dir {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.makeOpenPath(joined_path, opts);
}

FunctionstatFile[src]

pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.statFile(joined_path);
}

FunctionatomicFile[src]

pub fn atomicFile( p: Path, sub_path: []const u8, options: fs.Dir.AtomicFileOptions, buf: *[fs.max_path_bytes]u8, ) !fs.AtomicFile

Parameters

p: Path
sub_path: []const u8
buf: *[fs.max_path_bytes]u8

Source Code

Source code
pub fn atomicFile(
    p: Path,
    sub_path: []const u8,
    options: fs.Dir.AtomicFileOptions,
    buf: *[fs.max_path_bytes]u8,
) !fs.AtomicFile {
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.atomicFile(joined_path, options);
}

Functionaccess[src]

pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.access(joined_path, flags);
}

FunctionmakePath[src]

pub fn makePath(p: Path, sub_path: []const u8) !void

Parameters

p: Path
sub_path: []const u8

Source Code

Source code
pub fn makePath(p: Path, sub_path: []const u8) !void {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.makePath(joined_path);
}

FunctiontoString[src]

pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8

Parameters

p: Path
allocator: Allocator

Source Code

Source code
pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8 {
    return std.fmt.allocPrint(allocator, "{}", .{p});
}

FunctiontoStringZ[src]

pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8

Parameters

p: Path
allocator: Allocator

Source Code

Source code
pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 {
    return std.fmt.allocPrintZ(allocator, "{}", .{p});
}

Functionformat[src]

pub fn format( self: Path, comptime fmt_string: []const u8, options: std.fmt.FormatOptions, writer: anytype, ) !void

Parameters

self: Path
fmt_string: []const u8

Source Code

Source code
pub fn format(
    self: Path,
    comptime fmt_string: []const u8,
    options: std.fmt.FormatOptions,
    writer: anytype,
) !void {
    if (fmt_string.len == 1) {
        // Quote-escape the string.
        const stringEscape = std.zig.stringEscape;
        const f = switch (fmt_string[0]) {
            'q' => "",
            '\'' => "\'",
            else => @compileError("unsupported format string: " ++ fmt_string),
        };
        if (self.root_dir.path) |p| {
            try stringEscape(p, f, options, writer);
            if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer);
        }
        if (self.sub_path.len > 0) {
            try stringEscape(self.sub_path, f, options, writer);
        }
        return;
    }
    if (fmt_string.len > 0)
        std.fmt.invalidFmtError(fmt_string, self);
    if (std.fs.path.isAbsolute(self.sub_path)) {
        try writer.writeAll(self.sub_path);
        return;
    }
    if (self.root_dir.path) |p| {
        try writer.writeAll(p);
        if (self.sub_path.len > 0) {
            try writer.writeAll(fs.path.sep_str);
            try writer.writeAll(self.sub_path);
        }
        return;
    }
    if (self.sub_path.len > 0) {
        try writer.writeAll(self.sub_path);
        return;
    }
    try writer.writeByte('.');
}

Functioneql[src]

pub fn eql(self: Path, other: Path) bool

Parameters

self: Path
other: Path

Source Code

Source code
pub fn eql(self: Path, other: Path) bool {
    return self.root_dir.eql(other.root_dir) and std.mem.eql(u8, self.sub_path, other.sub_path);
}

FunctionsubPathOpt[src]

pub fn subPathOpt(self: Path) ?[]const u8

Parameters

self: Path

Source Code

Source code
pub fn subPathOpt(self: Path) ?[]const u8 {
    return if (self.sub_path.len == 0) null else self.sub_path;
}

FunctionsubPathOrDot[src]

pub fn subPathOrDot(self: Path) []const u8

Parameters

self: Path

Source Code

Source code
pub fn subPathOrDot(self: Path) []const u8 {
    return if (self.sub_path.len == 0) "." else self.sub_path;
}

Functionstem[src]

pub fn stem(p: Path) []const u8

Parameters

p: Path

Source Code

Source code
pub fn stem(p: Path) []const u8 {
    return fs.path.stem(p.sub_path);
}

Functionbasename[src]

pub fn basename(p: Path) []const u8

Parameters

p: Path

Source Code

Source code
pub fn basename(p: Path) []const u8 {
    return fs.path.basename(p.sub_path);
}

Source Code

Source code
root_dir: Cache.Directory,
/// The path, relative to the root dir, that this `Path` represents.
/// Empty string means the root_dir is the path.
sub_path: []const u8 = "",

pub fn clone(p: Path, arena: Allocator) Allocator.Error!Path {
    return .{
        .root_dir = try p.root_dir.clone(arena),
        .sub_path = try arena.dupe(u8, p.sub_path),
    };
}

pub fn cwd() Path {
    return initCwd("");
}

pub fn initCwd(sub_path: []const u8) Path {
    return .{ .root_dir = Cache.Directory.cwd(), .sub_path = sub_path };
}

pub fn join(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
    if (sub_path.len == 0) return p;
    const parts: []const []const u8 =
        if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
    return .{
        .root_dir = p.root_dir,
        .sub_path = try fs.path.join(arena, parts),
    };
}

pub fn resolvePosix(p: Path, arena: Allocator, sub_path: []const u8) Allocator.Error!Path {
    if (sub_path.len == 0) return p;
    return .{
        .root_dir = p.root_dir,
        .sub_path = try fs.path.resolvePosix(arena, &.{ p.sub_path, sub_path }),
    };
}

pub fn joinString(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Error![]u8 {
    const parts: []const []const u8 =
        if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
    return p.root_dir.join(gpa, parts);
}

pub fn joinStringZ(p: Path, gpa: Allocator, sub_path: []const u8) Allocator.Error![:0]u8 {
    const parts: []const []const u8 =
        if (p.sub_path.len == 0) &.{sub_path} else &.{ p.sub_path, sub_path };
    return p.root_dir.joinZ(gpa, parts);
}

pub fn openFile(
    p: Path,
    sub_path: []const u8,
    flags: fs.File.OpenFlags,
) !fs.File {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.openFile(joined_path, flags);
}

pub fn openDir(
    p: Path,
    sub_path: []const u8,
    args: fs.Dir.OpenOptions,
) fs.Dir.OpenError!fs.Dir {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.openDir(joined_path, args);
}

pub fn makeOpenPath(p: Path, sub_path: []const u8, opts: fs.Dir.OpenOptions) !fs.Dir {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.makeOpenPath(joined_path, opts);
}

pub fn statFile(p: Path, sub_path: []const u8) !fs.Dir.Stat {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.statFile(joined_path);
}

pub fn atomicFile(
    p: Path,
    sub_path: []const u8,
    options: fs.Dir.AtomicFileOptions,
    buf: *[fs.max_path_bytes]u8,
) !fs.AtomicFile {
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.atomicFile(joined_path, options);
}

pub fn access(p: Path, sub_path: []const u8, flags: fs.File.OpenFlags) !void {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.access(joined_path, flags);
}

pub fn makePath(p: Path, sub_path: []const u8) !void {
    var buf: [fs.max_path_bytes]u8 = undefined;
    const joined_path = if (p.sub_path.len == 0) sub_path else p: {
        break :p std.fmt.bufPrint(&buf, "{s}" ++ fs.path.sep_str ++ "{s}", .{
            p.sub_path, sub_path,
        }) catch return error.NameTooLong;
    };
    return p.root_dir.handle.makePath(joined_path);
}

pub fn toString(p: Path, allocator: Allocator) Allocator.Error![]u8 {
    return std.fmt.allocPrint(allocator, "{}", .{p});
}

pub fn toStringZ(p: Path, allocator: Allocator) Allocator.Error![:0]u8 {
    return std.fmt.allocPrintZ(allocator, "{}", .{p});
}

pub fn format(
    self: Path,
    comptime fmt_string: []const u8,
    options: std.fmt.FormatOptions,
    writer: anytype,
) !void {
    if (fmt_string.len == 1) {
        // Quote-escape the string.
        const stringEscape = std.zig.stringEscape;
        const f = switch (fmt_string[0]) {
            'q' => "",
            '\'' => "\'",
            else => @compileError("unsupported format string: " ++ fmt_string),
        };
        if (self.root_dir.path) |p| {
            try stringEscape(p, f, options, writer);
            if (self.sub_path.len > 0) try stringEscape(fs.path.sep_str, f, options, writer);
        }
        if (self.sub_path.len > 0) {
            try stringEscape(self.sub_path, f, options, writer);
        }
        return;
    }
    if (fmt_string.len > 0)
        std.fmt.invalidFmtError(fmt_string, self);
    if (std.fs.path.isAbsolute(self.sub_path)) {
        try writer.writeAll(self.sub_path);
        return;
    }
    if (self.root_dir.path) |p| {
        try writer.writeAll(p);
        if (self.sub_path.len > 0) {
            try writer.writeAll(fs.path.sep_str);
            try writer.writeAll(self.sub_path);
        }
        return;
    }
    if (self.sub_path.len > 0) {
        try writer.writeAll(self.sub_path);
        return;
    }
    try writer.writeByte('.');
}

pub fn eql(self: Path, other: Path) bool {
    return self.root_dir.eql(other.root_dir) and std.mem.eql(u8, self.sub_path, other.sub_path);
}

pub fn subPathOpt(self: Path) ?[]const u8 {
    return if (self.sub_path.len == 0) null else self.sub_path;
}

pub fn subPathOrDot(self: Path) []const u8 {
    return if (self.sub_path.len == 0) "." else self.sub_path;
}

pub fn stem(p: Path) []const u8 {
    return fs.path.stem(p.sub_path);
}

pub fn basename(p: Path) []const u8 {
    return fs.path.basename(p.sub_path);
}

/// Useful to make `Path` a key in `std.ArrayHashMap`.
pub const TableAdapter = struct {
    pub const Hash = std.hash.Wyhash;

    pub fn hash(self: TableAdapter, a: Cache.Path) u32 {
        _ = self;
        const seed = switch (@typeInfo(@TypeOf(a.root_dir.handle.fd))) {
            .pointer => @intFromPtr(a.root_dir.handle.fd),
            .int => @as(u32, @bitCast(a.root_dir.handle.fd)),
            else => @compileError("unimplemented hash function"),
        };
        return @truncate(Hash.hash(seed, a.sub_path));
    }
    pub fn eql(self: TableAdapter, a: Cache.Path, b: Cache.Path, b_index: usize) bool {
        _ = self;
        _ = b_index;
        return a.eql(b);
    }
};

const Path = @This();
const std = @import("../../std.zig");
const fs = std.fs;
const Allocator = std.mem.Allocator;
const Cache = std.Build.Cache;