123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { normalize, posix, sep } from './path.js';
- import { isWindows } from './platform.js';
- import { startsWithIgnoreCase } from './strings.js';
- export function isPathSeparator(code) {
- return code === 47 /* Slash */ || code === 92 /* Backslash */;
- }
- /**
- * Takes a Windows OS path and changes backward slashes to forward slashes.
- * This should only be done for OS paths from Windows (or user provided paths potentially from Windows).
- * Using it on a Linux or MaxOS path might change it.
- */
- export function toSlashes(osPath) {
- return osPath.replace(/[\\/]/g, posix.sep);
- }
- /**
- * Takes a Windows OS path (using backward or forward slashes) and turns it into a posix path:
- * - turns backward slashes into forward slashes
- * - makes it absolute if it starts with a drive letter
- * This should only be done for OS paths from Windows (or user provided paths potentially from Windows).
- * Using it on a Linux or MaxOS path might change it.
- */
- export function toPosixPath(osPath) {
- if (osPath.indexOf('/') === -1) {
- osPath = toSlashes(osPath);
- }
- if (/^[a-zA-Z]:(\/|$)/.test(osPath)) { // starts with a drive letter
- osPath = '/' + osPath;
- }
- return osPath;
- }
- /**
- * Computes the _root_ this path, like `getRoot('c:\files') === c:\`,
- * `getRoot('files:///files/path') === files:///`,
- * or `getRoot('\\server\shares\path') === \\server\shares\`
- */
- export function getRoot(path, sep = posix.sep) {
- if (!path) {
- return '';
- }
- const len = path.length;
- const firstLetter = path.charCodeAt(0);
- if (isPathSeparator(firstLetter)) {
- if (isPathSeparator(path.charCodeAt(1))) {
- // UNC candidate \\localhost\shares\ddd
- // ^^^^^^^^^^^^^^^^^^^
- if (!isPathSeparator(path.charCodeAt(2))) {
- let pos = 3;
- const start = pos;
- for (; pos < len; pos++) {
- if (isPathSeparator(path.charCodeAt(pos))) {
- break;
- }
- }
- if (start !== pos && !isPathSeparator(path.charCodeAt(pos + 1))) {
- pos += 1;
- for (; pos < len; pos++) {
- if (isPathSeparator(path.charCodeAt(pos))) {
- return path.slice(0, pos + 1) // consume this separator
- .replace(/[\\/]/g, sep);
- }
- }
- }
- }
- }
- // /user/far
- // ^
- return sep;
- }
- else if (isWindowsDriveLetter(firstLetter)) {
- // check for windows drive letter c:\ or c:
- if (path.charCodeAt(1) === 58 /* Colon */) {
- if (isPathSeparator(path.charCodeAt(2))) {
- // C:\fff
- // ^^^
- return path.slice(0, 2) + sep;
- }
- else {
- // C:
- // ^^
- return path.slice(0, 2);
- }
- }
- }
- // check for URI
- // scheme://authority/path
- // ^^^^^^^^^^^^^^^^^^^
- let pos = path.indexOf('://');
- if (pos !== -1) {
- pos += 3; // 3 -> "://".length
- for (; pos < len; pos++) {
- if (isPathSeparator(path.charCodeAt(pos))) {
- return path.slice(0, pos + 1); // consume this separator
- }
- }
- }
- return '';
- }
- export function isEqualOrParent(base, parentCandidate, ignoreCase, separator = sep) {
- if (base === parentCandidate) {
- return true;
- }
- if (!base || !parentCandidate) {
- return false;
- }
- if (parentCandidate.length > base.length) {
- return false;
- }
- if (ignoreCase) {
- const beginsWith = startsWithIgnoreCase(base, parentCandidate);
- if (!beginsWith) {
- return false;
- }
- if (parentCandidate.length === base.length) {
- return true; // same path, different casing
- }
- let sepOffset = parentCandidate.length;
- if (parentCandidate.charAt(parentCandidate.length - 1) === separator) {
- sepOffset--; // adjust the expected sep offset in case our candidate already ends in separator character
- }
- return base.charAt(sepOffset) === separator;
- }
- if (parentCandidate.charAt(parentCandidate.length - 1) !== separator) {
- parentCandidate += separator;
- }
- return base.indexOf(parentCandidate) === 0;
- }
- export function isWindowsDriveLetter(char0) {
- return char0 >= 65 /* A */ && char0 <= 90 /* Z */ || char0 >= 97 /* a */ && char0 <= 122 /* z */;
- }
- export function isRootOrDriveLetter(path) {
- const pathNormalized = normalize(path);
- if (isWindows) {
- if (path.length > 3) {
- return false;
- }
- return hasDriveLetter(pathNormalized) &&
- (path.length === 2 || pathNormalized.charCodeAt(2) === 92 /* Backslash */);
- }
- return pathNormalized === posix.sep;
- }
- export function hasDriveLetter(path, continueAsWindows) {
- const isWindowsPath = ((continueAsWindows !== undefined) ? continueAsWindows : isWindows);
- if (isWindowsPath) {
- return isWindowsDriveLetter(path.charCodeAt(0)) && path.charCodeAt(1) === 58 /* Colon */;
- }
- return false;
- }
|