820
821
basename(path: string, suffix?: string): string {
822
>
if (suffix !== undefined) {
path.ts
823
>
validateString(suffix, 'suffix');
824
>
}
825
>
validateString(path, 'path');
826
>
let start = 0;
827
>
let end = -1;
828
>
let matchedSlash = true;
829
>
let i;
830
>
831
>
// Check for a drive letter prefix so as not to mistake the following
832
>
// path separator as an extra separator at the end of the path that can be
833
>
// disregarded
834
>
if (path.length >= 2 &&
835
>
isWindowsDeviceRoot(path.charCodeAt(0)) &&
836
>
path.charCodeAt(1) === CHAR_COLON) {
837
>
start = 2;
838
>
}
839
>
840
>
if (suffix !== undefined && suffix.length > 0 && suffix.length <= path.length) {
841
>
if (suffix === path) {
842
>
return '';
843
>
}
844
>
let extIdx = suffix.length - 1;
845
>
let firstNonSlashEnd = -1;
846
>
for (i = path.length - 1; i >= start; --i) {
847
>
const code = path.charCodeAt(i);
848
>
if (isPathSeparator(code)) {
849
>
// If we reached a path separator that was not part of a set of path
850
>
// separators at the end of the string, stop now
851
>
if (!matchedSlash) {
852
>
start = i + 1;
853
>
break;
854
>
}
855
>
} else {
856
>
if (firstNonSlashEnd === -1) {
857
>
// We saw the first non-path separator, remember this index in case
858
>
// we need it if the extension ends up not matching
859
>
matchedSlash = false;
860
>
firstNonSlashEnd = i + 1;
861
>
}
862
>
if (extIdx >= 0) {
863
>
// Try to match the explicit extension
864
>
if (code === suffix.charCodeAt(extIdx)) {
865
>
if (--extIdx === -1) {
866
>
// We matched the extension, so mark this as the end of our path
867
>
// component
868
>
end = i;
869
>
}
870
>
} else {
871
// Extension does not match, so our result is the entire path
872
// component