Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

pathfix

  • Loading branch information...
commit 372c208691e0fe8ea3f7a63f31b0a71c94706ade 1 parent de97899
Bert Belder piscisaureus authored

Showing 2 changed files with 74 additions and 22 deletions. Show diff stats Hide diff stats

  1. +42 22 lib/path.js
  2. +32 0 test/simple/test-path.js
64 lib/path.js
@@ -55,15 +55,28 @@ function normalizeArray(parts, allowAboveRoot) {
55 55
56 56
57 57 if (isWindows) {
58   -
59   - // Regex to split a filename into [*, dir, basename, ext]
60   - // windows version
61   - var splitPathRe = /^(.+(?:[\\\/](?!$)|:)|[\\\/])?((?:.+?)?(\.[^.]*)?)$/;
62   -
63 58 // Regex to split a windows path into three parts: [*, device, slash,
64 59 // tail] windows-only
65 60 var splitDeviceRe =
66   - /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?(.*?)$/;
  61 + /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
  62 +
  63 + // Regex to split the tail part of the above into [*, dir, basename, ext]
  64 + var splitTailRe = /^([\s\S]+[\\\/](?!$)|[\\\/])?((?:[\s\S]+?)?(\.[^.]*)?)$/;
  65 +
  66 + // Function to split a filename into [root, dir, basename, ext]
  67 + // windows version
  68 + var splitPath = function(filename) {
  69 + // Separate device+slash from tail
  70 + var result = splitDeviceRe.exec(filename),
  71 + device = (result[1] || '') + (result[2] || ''),
  72 + tail = result[3] || '';
  73 + // Split the tail into dir, basename and extension
  74 + var result2 = splitTailRe.exec(tail),
  75 + dir = result2[1] || '',
  76 + basename = result2[2] || '',
  77 + ext = result2[3] || '';
  78 + return [device, dir, basename, ext];
  79 + }
67 80
68 81 // path.resolve([from ...], to)
69 82 // windows version
@@ -245,9 +258,13 @@ if (isWindows) {
245 258
246 259 } else /* posix */ {
247 260
248   - // Regex to split a filename into [*, dir, basename, ext]
249   - // posix version
250   - var splitPathRe = /^([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
  261 + // Split a filename into [root, dir, basename, ext], unix version
  262 + // 'root' is just a slash, or nothing.
  263 + var splitPathRe = /^(\/?)([\s\S]+\/(?!$)|\/)?((?:[\s\S]+?)?(\.[^.]*)?)$/;
  264 + var splitPath = function(filename) {
  265 + var result = splitPathRe.exec(filename);
  266 + return [result[1] || '', result[2] || '', result[3] || '', result[4] || ''];
  267 + };
251 268
252 269 // path.resolve([from ...], to)
253 270 // posix version
@@ -356,23 +373,26 @@ if (isWindows) {
356 373
357 374
358 375 exports.dirname = function(path) {
359   - var dir = splitPathRe.exec(path)[1] || '';
360   - if (!dir) {
361   - // No dirname
  376 + var result = splitPath(path),
  377 + root = result[0],
  378 + dir = result[1];
  379 +
  380 + if (!root && !dir) {
  381 + // No dirname whatsoever
362 382 return '.';
363   - } else if (dir.length === 1 ||
364   - (isWindows && dir.length <= 3 && dir.charAt(1) === ':')) {
365   - // It is just a slash or a drive letter with a slash
366   - return dir;
367   - } else {
368   - // It is a full dirname, strip trailing slash
369   - return dir.substring(0, dir.length - 1);
370 383 }
  384 +
  385 + if (dir) {
  386 + // It has a dirname, strip trailing slash
  387 + dir = dir.substring(0, dir.length - 1);
  388 + }
  389 +
  390 + return root + dir;
371 391 };
372 392
373 393
374 394 exports.basename = function(path, ext) {
375   - var f = splitPathRe.exec(path)[2] || '';
  395 + var f = splitPath(path)[2];
376 396 // TODO: make this comparison case-insensitive on windows?
377 397 if (ext && f.substr(-1 * ext.length) === ext) {
378 398 f = f.substr(0, f.length - ext.length);
@@ -381,8 +401,8 @@ exports.basename = function(path, ext) {
381 401 };
382 402
383 403
384   -exports.extname = function(path) {
385   - return splitPathRe.exec(path)[3] || '';
  404 +exports.extname = function (path) {
  405 + return splitPath(path)[3];
386 406 };
387 407
388 408
32 test/simple/test-path.js
@@ -39,11 +39,43 @@ if (!isWindows) {
39 39 }
40 40
41 41 assert.equal(path.extname(f), '.js');
  42 +
42 43 assert.equal(path.dirname(f).substr(-11), isWindows ? 'test\\simple' : 'test/simple');
43 44 assert.equal(path.dirname('/a/b/'), '/a');
44 45 assert.equal(path.dirname('/a/b'), '/a');
45 46 assert.equal(path.dirname('/a'), '/');
46 47 assert.equal(path.dirname('/'), '/');
  48 +
  49 +if (isWindows) {
  50 + assert.equal(path.dirname('c:\\'), 'c:\\');
  51 + assert.equal(path.dirname('c:\\foo'), 'c:\\');
  52 + assert.equal(path.dirname('c:\\foo\\'), 'c:\\');
  53 + assert.equal(path.dirname('c:\\foo\\bar'), 'c:\\foo');
  54 + assert.equal(path.dirname('c:\\foo\\bar\\'), 'c:\\foo');
  55 + assert.equal(path.dirname('c:\\foo\\bar\\baz'), 'c:\\foo\\bar');
  56 + assert.equal(path.dirname('\\'), '\\');
  57 + assert.equal(path.dirname('\\foo'), '\\');
  58 + assert.equal(path.dirname('\\foo\\'), '\\');
  59 + assert.equal(path.dirname('\\foo\\bar'), '\\foo');
  60 + assert.equal(path.dirname('\\foo\\bar\\'), '\\foo');
  61 + assert.equal(path.dirname('\\foo\\bar\\baz'), '\\foo\\bar');
  62 + assert.equal(path.dirname('c:'), 'c:');
  63 + assert.equal(path.dirname('c:foo'), 'c:');
  64 + assert.equal(path.dirname('c:foo\\'), 'c:');
  65 + assert.equal(path.dirname('c:foo\\bar'), 'c:foo');
  66 + assert.equal(path.dirname('c:foo\\bar\\'), 'c:foo');
  67 + assert.equal(path.dirname('c:foo\\bar\\baz'), 'c:foo\\bar');
  68 + assert.equal(path.dirname('\\\\unc\\share'), '\\\\unc\\share');
  69 + assert.equal(path.dirname('\\\\unc\\share\\foo'), '\\\\unc\\share\\');
  70 + assert.equal(path.dirname('\\\\unc\\share\\foo\\'), '\\\\unc\\share\\');
  71 + assert.equal(path.dirname('\\\\unc\\share\\foo\\bar'),
  72 + '\\\\unc\\share\\foo');
  73 + assert.equal(path.dirname('\\\\unc\\share\\foo\\bar\\'),
  74 + '\\\\unc\\share\\foo');
  75 + assert.equal(path.dirname('\\\\unc\\share\\foo\\bar\\baz'),
  76 + '\\\\unc\\share\\foo\\bar');
  77 +}
  78 +
47 79 path.exists(f, function(y) { assert.equal(y, true) });
48 80
49 81 assert.equal(path.existsSync(f), true);

0 comments on commit 372c208

Please sign in to comment.
Something went wrong with that request. Please try again.