| ... | ... | @@ -749,8 +749,12 @@ fn testResolvePosix(paths: []const []const u8, expected: []const u8) !void { |
| 749 | 749 | return testing.expect(mem.eql(u8, actual, expected)); |
| 750 | 750 | } |
| 751 | 751 | |
| 752 | /// Strip the last component from a file path. |
| 753 | /// |
| 752 | 754 | /// If the path is a file in the current directory (no directory component) |
| 753 | | /// then returns null |
| 755 | /// then returns null. |
| 756 | /// |
| 757 | /// If the path is the root directory, returns null. |
| 754 | 758 | pub fn dirname(path: []const u8) ?[]const u8 { |
| 755 | 759 | if (builtin.os.tag == .windows) { |
| 756 | 760 | return dirnameWindows(path); |
| ... | ... | @@ -765,19 +769,19 @@ pub fn dirnameWindows(path: []const u8) ?[]const u8 { |
| 765 | 769 | |
| 766 | 770 | const root_slice = diskDesignatorWindows(path); |
| 767 | 771 | if (path.len == root_slice.len) |
| 768 | | return path; |
| 772 | return null; |
| 769 | 773 | |
| 770 | 774 | const have_root_slash = path.len > root_slice.len and (path[root_slice.len] == '/' or path[root_slice.len] == '\\'); |
| 771 | 775 | |
| 772 | 776 | var end_index: usize = path.len - 1; |
| 773 | 777 | |
| 774 | | while ((path[end_index] == '/' or path[end_index] == '\\') and end_index > root_slice.len) { |
| 778 | while (path[end_index] == '/' or path[end_index] == '\\') { |
| 775 | 779 | if (end_index == 0) |
| 776 | 780 | return null; |
| 777 | 781 | end_index -= 1; |
| 778 | 782 | } |
| 779 | 783 | |
| 780 | | while (path[end_index] != '/' and path[end_index] != '\\' and end_index > root_slice.len) { |
| 784 | while (path[end_index] != '/' and path[end_index] != '\\') { |
| 781 | 785 | if (end_index == 0) |
| 782 | 786 | return null; |
| 783 | 787 | end_index -= 1; |
| ... | ... | @@ -800,7 +804,7 @@ pub fn dirnamePosix(path: []const u8) ?[]const u8 { |
| 800 | 804 | var end_index: usize = path.len - 1; |
| 801 | 805 | while (path[end_index] == '/') { |
| 802 | 806 | if (end_index == 0) |
| 803 | | return path[0..1]; |
| 807 | return null; |
| 804 | 808 | end_index -= 1; |
| 805 | 809 | } |
| 806 | 810 | |
| ... | ... | @@ -810,7 +814,7 @@ pub fn dirnamePosix(path: []const u8) ?[]const u8 { |
| 810 | 814 | end_index -= 1; |
| 811 | 815 | } |
| 812 | 816 | |
| 813 | | if (end_index == 0 and path[end_index] == '/') |
| 817 | if (end_index == 0 and path[0] == '/') |
| 814 | 818 | return path[0..1]; |
| 815 | 819 | |
| 816 | 820 | if (end_index == 0) |
| ... | ... | @@ -823,8 +827,10 @@ test "dirnamePosix" { |
| 823 | 827 | testDirnamePosix("/a/b/c", "/a/b"); |
| 824 | 828 | testDirnamePosix("/a/b/c///", "/a/b"); |
| 825 | 829 | testDirnamePosix("/a", "/"); |
| 826 | | testDirnamePosix("/", "/"); |
| 827 | | testDirnamePosix("////", "/"); |
| 830 | testDirnamePosix("/", null); |
| 831 | testDirnamePosix("//", null); |
| 832 | testDirnamePosix("///", null); |
| 833 | testDirnamePosix("////", null); |
| 828 | 834 | testDirnamePosix("", null); |
| 829 | 835 | testDirnamePosix("a", null); |
| 830 | 836 | testDirnamePosix("a/", null); |
| ... | ... | @@ -832,27 +838,27 @@ test "dirnamePosix" { |
| 832 | 838 | } |
| 833 | 839 | |
| 834 | 840 | test "dirnameWindows" { |
| 835 | | testDirnameWindows("c:\\", "c:\\"); |
| 841 | testDirnameWindows("c:\\", null); |
| 836 | 842 | testDirnameWindows("c:\\foo", "c:\\"); |
| 837 | 843 | testDirnameWindows("c:\\foo\\", "c:\\"); |
| 838 | 844 | testDirnameWindows("c:\\foo\\bar", "c:\\foo"); |
| 839 | 845 | testDirnameWindows("c:\\foo\\bar\\", "c:\\foo"); |
| 840 | 846 | testDirnameWindows("c:\\foo\\bar\\baz", "c:\\foo\\bar"); |
| 841 | | testDirnameWindows("\\", "\\"); |
| 847 | testDirnameWindows("\\", null); |
| 842 | 848 | testDirnameWindows("\\foo", "\\"); |
| 843 | 849 | testDirnameWindows("\\foo\\", "\\"); |
| 844 | 850 | testDirnameWindows("\\foo\\bar", "\\foo"); |
| 845 | 851 | testDirnameWindows("\\foo\\bar\\", "\\foo"); |
| 846 | 852 | testDirnameWindows("\\foo\\bar\\baz", "\\foo\\bar"); |
| 847 | | testDirnameWindows("c:", "c:"); |
| 848 | | testDirnameWindows("c:foo", "c:"); |
| 849 | | testDirnameWindows("c:foo\\", "c:"); |
| 853 | testDirnameWindows("c:", null); |
| 854 | testDirnameWindows("c:foo", null); |
| 855 | testDirnameWindows("c:foo\\", null); |
| 850 | 856 | testDirnameWindows("c:foo\\bar", "c:foo"); |
| 851 | 857 | testDirnameWindows("c:foo\\bar\\", "c:foo"); |
| 852 | 858 | testDirnameWindows("c:foo\\bar\\baz", "c:foo\\bar"); |
| 853 | 859 | testDirnameWindows("file:stream", null); |
| 854 | 860 | testDirnameWindows("dir\\file:stream", "dir"); |
| 855 | | testDirnameWindows("\\\\unc\\share", "\\\\unc\\share"); |
| 861 | testDirnameWindows("\\\\unc\\share", null); |
| 856 | 862 | testDirnameWindows("\\\\unc\\share\\foo", "\\\\unc\\share\\"); |
| 857 | 863 | testDirnameWindows("\\\\unc\\share\\foo\\", "\\\\unc\\share\\"); |
| 858 | 864 | testDirnameWindows("\\\\unc\\share\\foo\\bar", "\\\\unc\\share\\foo"); |
| ... | ... | @@ -862,8 +868,8 @@ test "dirnameWindows" { |
| 862 | 868 | testDirnameWindows("/a/b", "/a"); |
| 863 | 869 | testDirnameWindows("/a", "/"); |
| 864 | 870 | testDirnameWindows("", null); |
| 865 | | testDirnameWindows("/", "/"); |
| 866 | | testDirnameWindows("////", "/"); |
| 871 | testDirnameWindows("/", null); |
| 872 | testDirnameWindows("////", null); |
| 867 | 873 | testDirnameWindows("foo", null); |
| 868 | 874 | } |
| 869 | 875 | |