diff options
| author | Andrew Kelley <superjoe30@gmail.com> | 2017-10-08 19:18:47 -0400 |
|---|---|---|
| committer | Andrew Kelley <superjoe30@gmail.com> | 2017-10-08 21:44:17 -0400 |
| commit | e15e1e09f087b8d1f4d80d90a88e2944ead13332 (patch) | |
| tree | f51a253cfabadbba631f799bcdf49b0e8ea35bfe /std | |
| parent | dcf5c9074e8a0feab204200d74831fda10e6c625 (diff) | |
| download | zig-e15e1e09f087b8d1f4d80d90a88e2944ead13332.tar.gz zig-e15e1e09f087b8d1f4d80d90a88e2944ead13332.zip | |
os.path.basename implementation for windows
Diffstat (limited to 'std')
| -rw-r--r-- | std/os/path.zig | 74 |
1 files changed, 72 insertions, 2 deletions
diff --git a/std/os/path.zig b/std/os/path.zig index bb4334228a..133b3d70ef 100644 --- a/std/os/path.zig +++ b/std/os/path.zig @@ -610,9 +610,14 @@ fn testDirnameWindows(input: []const u8, expected_output: []const u8) { } pub fn basename(path: []const u8) -> []const u8 { - if (builtin.os == builtin.Os.windows) { - @compileError("TODO implement os.path.basename for windows"); + if (is_windows) { + return basenameWindows(path); + } else { + return basenamePosix(path); } +} + +pub fn basenamePosix(path: []const u8) -> []const u8 { if (path.len == 0) return []u8{}; @@ -633,6 +638,38 @@ pub fn basename(path: []const u8) -> []const u8 { return path[start_index + 1..end_index]; } +pub fn basenameWindows(path: []const u8) -> []const u8 { + if (path.len == 0) + return []u8{}; + + var end_index: usize = path.len - 1; + while (true) { + const byte = path[end_index]; + if (byte == '/' or byte == '\\') { + if (end_index == 0) + return []u8{}; + end_index -= 1; + continue; + } + if (byte == ':' and end_index == 1) { + return []u8{}; + } + break; + } + + var start_index: usize = end_index; + end_index += 1; + while (path[start_index] != '/' and path[start_index] != '\\' and + !(path[start_index] == ':' and start_index == 1)) + { + if (start_index == 0) + return path[0..end_index]; + start_index -= 1; + } + + return path[start_index + 1..end_index]; +} + test "os.path.basename" { testBasename("", ""); testBasename("/", ""); @@ -646,11 +683,44 @@ test "os.path.basename" { testBasename("/aaa/b", "b"); testBasename("/a/b", "b"); testBasename("//a", "a"); + + testBasenamePosix("\\dir\\basename.ext", "\\dir\\basename.ext"); + testBasenamePosix("\\basename.ext", "\\basename.ext"); + testBasenamePosix("basename.ext", "basename.ext"); + testBasenamePosix("basename.ext\\", "basename.ext\\"); + testBasenamePosix("basename.ext\\\\", "basename.ext\\\\"); + testBasenamePosix("foo", "foo"); + + testBasenameWindows("\\dir\\basename.ext", "basename.ext"); + testBasenameWindows("\\basename.ext", "basename.ext"); + testBasenameWindows("basename.ext", "basename.ext"); + testBasenameWindows("basename.ext\\", "basename.ext"); + testBasenameWindows("basename.ext\\\\", "basename.ext"); + testBasenameWindows("foo", "foo"); + testBasenameWindows("C:", ""); + testBasenameWindows("C:.", "."); + testBasenameWindows("C:\\", ""); + testBasenameWindows("C:\\dir\\base.ext", "base.ext"); + testBasenameWindows("C:\\basename.ext", "basename.ext"); + testBasenameWindows("C:basename.ext", "basename.ext"); + testBasenameWindows("C:basename.ext\\", "basename.ext"); + testBasenameWindows("C:basename.ext\\\\", "basename.ext"); + testBasenameWindows("C:foo", "foo"); + testBasenameWindows("file:stream", "file:stream"); } + fn testBasename(input: []const u8, expected_output: []const u8) { assert(mem.eql(u8, basename(input), expected_output)); } +fn testBasenamePosix(input: []const u8, expected_output: []const u8) { + assert(mem.eql(u8, basenamePosix(input), expected_output)); +} + +fn testBasenameWindows(input: []const u8, expected_output: []const u8) { + assert(mem.eql(u8, basenameWindows(input), expected_output)); +} + /// Returns the relative path from ::from to ::to. If ::from and ::to each /// resolve to the same path (after calling ::resolve on each), a zero-length /// string is returned. |
