Zig 0.17.0-dev (Split by item)

Shortcut keys
?
Show these tips
S
Focus search field
Esc
Clear focus & close tips
U
Jump to source code
↑
Move up in search results
↓
Move down in search results
↵
Go to active search result
This is an example of documentation generated by ZigDoc, an alternative to Zig's built-in Auto Doc feature. See also examples in other modes/formats. The project being documented here (as the example) is the Zig standard library. Public Function

getWin32PathType

Public Function
std.fs.path.getWin32PathType
pub fn getWin32PathType(comptime T: type, path: []const T) Win32PathType

Get the path type of a Win32 namespace path. Similar to RtlDetermineDosPathNameType_U. If T is u16, then path should be encoded as WTF-16LE.

Params

  • T: type
  • path: []const T

File

fs/path.zig:2596
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
pub fn getWin32PathType(comptime T: type, path: []const T) Win32PathType {
    if (path.len < 1) return .relative;

    const windows_path = std.fs.path.PathType.windows;
    if (windows_path.isSep(T, path[0])) {
        // \x
        if (path.len < 2 or !windows_path.isSep(T, path[1])) return .rooted;
        // \\. or \\?
        if (path.len > 2 and (path[2] == mem.nativeToLittle(T, '.') or path[2] == mem.nativeToLittle(T, '?'))) {
            // exactly \\. or \\? with nothing trailing
            if (path.len == 3) return .root_local_device;
            // \\.\x or \\?\x
            if (windows_path.isSep(T, path[3])) return .local_device;
        }
        // \\x
        return .unc_absolute;
    } else {
        // Some choice has to be made about how non-ASCII code points as drive-letters are handled, since
        // path[0] is a different size for WTF-16 vs WTF-8, leading to a potential mismatch in classification
        // for a WTF-8 path and its WTF-16 equivalent. For example, `€:\` encoded in WTF-16 is three code
        // units `<0x20AC>:\` whereas `€:\` encoded as WTF-8 is 6 code units `<0xE2><0x82><0xAC>:\` so
        // checking path[0], path[1] and path[2] would not behave the same between WTF-8/WTF-16.
        //
        // `RtlDetermineDosPathNameType_U` exclusively deals with WTF-16 and considers
        // `€:\` a drive-absolute path, but code points that take two WTF-16 code units to encode get
        // classified as a relative path (e.g. with U+20000 as the drive-letter that'd be encoded
        // in WTF-16 as `<0xD840><0xDC00>:\` and be considered a relative path).
        //
        // The choice made here is to emulate the behavior of `RtlDetermineDosPathNameType_U` for both
        // WTF-16 and WTF-8. This is because, while unlikely and not supported by the Disk Manager GUI,
        // drive letters are not actually restricted to A-Z. Using `SetVolumeMountPointW` will allow you
        // to set any byte value as a drive letter, and going through `IOCTL_MOUNTMGR_CREATE_POINT` will
        // allow you to set any WTF-16 code unit as a drive letter.
        //
        // Non-A-Z drive letters don't interact well with most of Windows, but certain things do work, e.g.
        // `cd /D €:\` will work, filesystem functions still work, etc.
        //
        // The unfortunate part of this is that this makes handling WTF-8 more complicated as we can't
        // just check path[0], path[1], path[2].
        const colon_i: usize = switch (T) {
            u8 => i: {
                const code_point_len = std.unicode.utf8ByteSequenceLength(path[0]) catch return .relative;
                // Conveniently, 4-byte sequences in WTF-8 have the same starting code point
                // as 2-code-unit sequences in WTF-16.
                if (code_point_len > 3) return .relative;
                break :i code_point_len;
            },
            u16 => 1,
            else => @compileError("unsupported type: " ++ @typeName(T)),
        };
        // x
        if (path.len < colon_i + 1 or path[colon_i] != mem.nativeToLittle(T, ':')) return .relative;
        // x:\
        if (path.len > colon_i + 1 and windows_path.isSep(T, path[colon_i + 1])) return .drive_absolute;
        // x:
        return .drive_relative;
    }
}