aboutsummaryrefslogtreecommitdiff
path: root/lib/std/fs
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2020-12-11 19:32:21 -0500
committerGitHub <noreply@github.com>2020-12-11 19:32:21 -0500
commit1852dc7e13b49a0b3238b8d654d09c4fc91aa3e4 (patch)
tree1898f8a94bcf06b0c6cf45a30c8497fcadac8c6b /lib/std/fs
parentc4f53d1ef65b7942383471876e02a1bd03d37dd9 (diff)
parentb3af2f68b38c542f7d8bb5b1292c5301a07f9cac (diff)
downloadzig-1852dc7e13b49a0b3238b8d654d09c4fc91aa3e4.tar.gz
zig-1852dc7e13b49a0b3238b8d654d09c4fc91aa3e4.zip
Merge pull request #7098 from MasterQ32/std.fs.path.extension
Implements std.fs.path.extension
Diffstat (limited to 'lib/std/fs')
-rw-r--r--lib/std/fs/path.zig68
1 files changed, 68 insertions, 0 deletions
diff --git a/lib/std/fs/path.zig b/lib/std/fs/path.zig
index 1bf2211372..8f1aaee554 100644
--- a/lib/std/fs/path.zig
+++ b/lib/std/fs/path.zig
@@ -28,6 +28,7 @@ pub const delimiter_windows = ';';
pub const delimiter_posix = ':';
pub const delimiter = if (builtin.os.tag == .windows) delimiter_windows else delimiter_posix;
+/// Returns if the given byte is a valid path separator
pub fn isSep(byte: u8) bool {
if (builtin.os.tag == .windows) {
return byte == '/' or byte == '\\';
@@ -1188,3 +1189,70 @@ fn testRelativeWindows(from: []const u8, to: []const u8, expected_output: []cons
defer testing.allocator.free(result);
testing.expectEqualSlices(u8, expected_output, result);
}
+
+/// Returns the extension of the file name (if any).
+/// This function will search for the file extension (separated by a `.`) and will return the text after the `.`.
+/// Files that end with `.` are considered to have no extension, files that start with `.`
+/// Examples:
+/// - `"main.zig"` ⇒ `".zig"`
+/// - `"src/main.zig"` ⇒ `".zig"`
+/// - `".gitignore"` ⇒ `""`
+/// - `"keep."` ⇒ `""`
+/// - `"src.keep.me"` ⇒ `".me"`
+/// - `"/src/keep.me"` ⇒ `".me"`
+/// - `"/src/keep.me/"` ⇒ `".me"`
+pub fn extension(path: []const u8) []const u8 {
+ const filename = basename(path);
+ return if (std.mem.lastIndexOf(u8, filename, ".")) |index|
+ if (index == 0 or index == filename.len - 1)
+ ""
+ else
+ filename[index..]
+ else
+ "";
+}
+
+fn testExtension(path: []const u8, expected: []const u8) void {
+ std.testing.expectEqualStrings(expected, extension(path));
+}
+
+test "extension" {
+ testExtension("", "");
+ testExtension(".", "");
+ testExtension("a.", "");
+ testExtension("abc.", "");
+ testExtension(".a", "");
+ testExtension(".file", "");
+ testExtension(".gitignore", "");
+ testExtension("file.ext", ".ext");
+ testExtension("file.ext.", "");
+ testExtension("very-long-file.bruh", ".bruh");
+ testExtension("a.b.c", ".c");
+ testExtension("a.b.c/", ".c");
+
+ testExtension("/", "");
+ testExtension("/.", "");
+ testExtension("/a.", "");
+ testExtension("/abc.", "");
+ testExtension("/.a", "");
+ testExtension("/.file", "");
+ testExtension("/.gitignore", "");
+ testExtension("/file.ext", ".ext");
+ testExtension("/file.ext.", "");
+ testExtension("/very-long-file.bruh", ".bruh");
+ testExtension("/a.b.c", ".c");
+ testExtension("/a.b.c/", ".c");
+
+ testExtension("/foo/bar/bam/", "");
+ testExtension("/foo/bar/bam/.", "");
+ testExtension("/foo/bar/bam/a.", "");
+ testExtension("/foo/bar/bam/abc.", "");
+ testExtension("/foo/bar/bam/.a", "");
+ testExtension("/foo/bar/bam/.file", "");
+ testExtension("/foo/bar/bam/.gitignore", "");
+ testExtension("/foo/bar/bam/file.ext", ".ext");
+ testExtension("/foo/bar/bam/file.ext.", "");
+ testExtension("/foo/bar/bam/very-long-file.bruh", ".bruh");
+ testExtension("/foo/bar/bam/a.b.c", ".c");
+ testExtension("/foo/bar/bam/a.b.c/", ".c");
+}