summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBert Belder <bertbelder@gmail.com>2011-09-06 04:46:44 +0200
committerBert Belder <bertbelder@gmail.com>2011-09-06 04:47:36 +0200
commit8153a216137728bdb3942d70f4aa52d4644b2ad2 (patch)
treea699e9d53b25eff6483fb332166b40072e363503
parent2d9ab49239d475cad3126384daefc6f365555dd9 (diff)
downloadandroid-node-v8-8153a216137728bdb3942d70f4aa52d4644b2ad2.tar.gz
android-node-v8-8153a216137728bdb3942d70f4aa52d4644b2ad2.tar.bz2
android-node-v8-8153a216137728bdb3942d70f4aa52d4644b2ad2.zip
Improve path parsing on windows
Closes #650
-rw-r--r--lib/path.js62
-rw-r--r--test/simple/test-path.js32
2 files changed, 73 insertions, 21 deletions
diff --git a/lib/path.js b/lib/path.js
index 1c60180963..18f7bb7fef 100644
--- a/lib/path.js
+++ b/lib/path.js
@@ -55,15 +55,28 @@ function normalizeArray(parts, allowAboveRoot) {
if (isWindows) {
-
- // Regex to split a filename into [*, dir, basename, ext]
- // windows version
- var splitPathRe = /^(.+(?:[\\\/](?!$)|:)|[\\\/])?((?:.+?)?(\.[^.]*)?)$/;
-
// Regex to split a windows path into three parts: [*, device, slash,
// tail] windows-only
var splitDeviceRe =
- /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?(.*?)$/;
+ /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
+
+ // Regex to split the tail part of the above into [*, dir, basename, ext]
+ var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+
+ // Function to split a filename into [root, dir, basename, ext]
+ // windows version
+ var splitPath = function(filename) {
+ // Separate device+slash from tail
+ var result = splitDeviceRe.exec(filename),
+ device = (result[1] || '') + (result[2] || ''),
+ tail = result[3] || '';
+ // Split the tail into dir, basename and extension
+ var result2 = splitTailRe.exec(tail),
+ dir = result2[1] || '',
+ basename = result2[2] || '',
+ ext = result2[3] || '';
+ return [device, dir, basename, ext];
+ }
// path.resolve([from ...], to)
// windows version
@@ -245,9 +258,13 @@ if (isWindows) {
} else /* posix */ {
- // Regex to split a filename into [*, dir, basename, ext]
- // posix version
- var splitPathRe = /^([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+ // Split a filename into [root, dir, basename, ext], unix version
+ // 'root' is just a slash, or nothing.
+ var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
+ var splitPath = function(filename) {
+ var result = splitPathRe.exec(filename);
+ return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
+ };
// path.resolve([from ...], to)
// posix version
@@ -356,23 +373,26 @@ if (isWindows) {
exports.dirname = function(path) {
- var dir = splitPathRe.exec(path)[1] || '';
- if (!dir) {
- // No dirname
+ var result = splitPath(path),
+ root = result[0],
+ dir = result[1];
+
+ if (!root && !dir) {
+ // No dirname whatsoever
return '.';
- } else if (dir.length === 1 ||
- (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
- // It is just a slash or a drive letter with a slash
- return dir;
- } else {
- // It is a full dirname, strip trailing slash
- return dir.substring(0, dir.length - 1);
}
+
+ if (dir) {
+ // It has a dirname, strip trailing slash
+ dir = dir.substring(0, dir.length - 1);
+ }
+
+ return root + dir;
};
exports.basename = function(path, ext) {
- var f = splitPathRe.exec(path)[2] || '';
+ var f = splitPath(path)[2];
// TODO: make this comparison case-insensitive on windows?
if (ext && f.substr(-1 * ext.length) === ext) {
f = f.substr(0, f.length - ext.length);
@@ -382,7 +402,7 @@ exports.basename = function(path, ext) {
exports.extname = function(path) {
- return splitPathRe.exec(path)[3] || '';
+ return splitPath(path)[3];
};
diff --git a/test/simple/test-path.js b/test/simple/test-path.js
index 3d72ad733e..7fe80ecd53 100644
--- a/test/simple/test-path.js
+++ b/test/simple/test-path.js
@@ -39,11 +39,43 @@ if (!isWindows) {
}
assert.equal(path.extname(f), '.js');
+
assert.equal(path.dirname(f).substr(-11), isWindows ? 'test\\simple' : 'test/simple');
assert.equal(path.dirname('/a/b/'), '/a');
assert.equal(path.dirname('/a/b'), '/a');
assert.equal(path.dirname('/a'), '/');
assert.equal(path.dirname('/'), '/');
+
+if (isWindows) {
+ assert.equal(path.dirname('c:\\'), 'c:\\');
+ assert.equal(path.dirname('c:\\foo'), 'c:\\');
+ assert.equal(path.dirname('c:\\foo\\'), 'c:\\');
+ assert.equal(path.dirname('c:\\foo\\bar'), 'c:\\foo');
+ assert.equal(path.dirname('c:\\foo\\bar\\'), 'c:\\foo');
+ assert.equal(path.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar');
+ assert.equal(path.dirname('\\'), '\\');
+ assert.equal(path.dirname('\\foo'), '\\');
+ assert.equal(path.dirname('\\foo\\'), '\\');
+ assert.equal(path.dirname('\\foo\\bar'), '\\foo');
+ assert.equal(path.dirname('\\foo\\bar\\'), '\\foo');
+ assert.equal(path.dirname('\\foo\\bar\\baz'), '\\foo\\bar');
+ assert.equal(path.dirname('c:'), 'c:');
+ assert.equal(path.dirname('c:foo'), 'c:');
+ assert.equal(path.dirname('c:foo\\'), 'c:');
+ assert.equal(path.dirname('c:foo\\bar'), 'c:foo');
+ assert.equal(path.dirname('c:foo\\bar\\'), 'c:foo');
+ assert.equal(path.dirname('c:foo\\bar\\baz'), 'c:foo\\bar');
+ assert.equal(path.dirname('\\\\unc\\share'), '\\\\unc\\share');
+ assert.equal(path.dirname('\\\\unc\\share\\foo'), '\\\\unc\\share\\');
+ assert.equal(path.dirname('\\\\unc\\share\\foo\\'), '\\\\unc\\share\\');
+ assert.equal(path.dirname('\\\\unc\\share\\foo\\bar'),
+ '\\\\unc\\share\\foo');
+ assert.equal(path.dirname('\\\\unc\\share\\foo\\bar\\'),
+ '\\\\unc\\share\\foo');
+ assert.equal(path.dirname('\\\\unc\\share\\foo\\bar\\baz'),
+ '\\\\unc\\share\\foo\\bar');
+}
+
path.exists(f, function(y) { assert.equal(y, true) });
assert.equal(path.existsSync(f), true);