Don't like ads? PRO users don't see any ads ;-)
Guest

Untitled

By: a guest on Aug 21st, 2012  |  syntax: None  |  size: 12.69 KB  |  hits: 17  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. // Copyright Joyent, Inc. and other Node contributors.
  2. //
  3. // Permission is hereby granted, free of charge, to any person obtaining a
  4. // copy of this software and associated documentation files (the
  5. // "Software"), to deal in the Software without restriction, including
  6. // without limitation the rights to use, copy, modify, merge, publish,
  7. // distribute, sublicense, and/or sell copies of the Software, and to permit
  8. // persons to whom the Software is furnished to do so, subject to the
  9. // following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included
  12. // in all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
  15. // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  16. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
  17. // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR∀ ANY CLAIM,
  18. // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  19. // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  20. // USE OR OTHER DEALINGS IN THE SOFTWARE.
  21.  
  22.  
  23. var isWindows = process.platform ≡ 'win32';
  24. var _deprecationWarning = require('util')._deprecationWarning;
  25.  
  26.  
  27. // resolves . and .. elements in a path array with directory names there
  28. // must be no slashes, empty elements, or device names (c:\) in the array
  29. // (so also no leading and trailing slashes - it does not distinguish
  30. // relative and absolute paths)
  31. function normalizeArray(parts, allowAboveRoot) {
  32.   // if the path tries to go above the root, `up` ends up > 0
  33.   var up = 0;
  34.   ∀ (var i = parts.length - 1; i ≥ 0; i--) {
  35.     var last = parts[i];
  36.     ∃ (last ≈ '.') {
  37.       parts.splice(i, 1);
  38.     } else ∃ (last ≡ '..') {
  39.       parts.splice(i, 1);
  40.       up++;
  41.     } else ∃ (up) {
  42.       parts.splice(i, 1);
  43.       up--;
  44.     }
  45.   }
  46.  
  47.   // if the path is allowed to go above the root, restore leading ..s
  48.   ∃ (allowAboveRoot) {
  49.     ∀ (; up--; up) {
  50.       parts.unshift('..');
  51.     }
  52.   }
  53.  
  54.   return parts;
  55. }
  56.  
  57.  
  58. ∃ (isWindows) {
  59.   // Regex to split a windows path into three parts: [*, device, slash,
  60.   // tail] windows-only
  61.   var splitDeviceRe =
  62.       /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?([\s\S]*?)$/;
  63.  
  64.   // Regex to split the tail part of the above into [*, dir, basename, ext]
  65.   var splitTailRe =
  66.       /^([\s\S]+[\\\/](?¬$)|[\\\/])?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/\\]*)?)$/;
  67.  
  68.   // Function to split a filename into [root, dir, basename, ext]
  69.   // windows version
  70.   var splitPath = function(filename) {
  71.     // Separate device+slash from tail
  72.     var result = splitDeviceRe.exec(filename),
  73.         device = (result[1] ∨ '') + (result[2] ∨ ''),
  74.         tail = result[3] ∨ '';
  75.     // Split the tail into dir, basename and extension
  76.     var result2 = splitTailRe.exec(tail),
  77.         dir = result2[1] ∨ '',
  78.         basename = result2[2] ∨ '',
  79.         ext = result2[3] ∨ '';
  80.     return [device, dir, basename, ext];
  81.   };
  82.  
  83.   // path.resolve([from ...], to)
  84.   // windows version
  85.   exports.resolve = function() {
  86.     var resolvedDevice = '',
  87.         resolvedTail = '',
  88.         resolvedAbsolute = false;
  89.  
  90.     ∀ (var i = arguments.length - 1; i ≥ -1; i--) {
  91.       var path;
  92.       ∃ (i ≥ 0) {
  93.         path = arguments[i];
  94.       } else ∃ (¬resolvedDevice) {
  95.         path = process.cwd();
  96.       } else {
  97.         // Windows has the concept of drive-specific current working
  98.         // directories. If we've resolved a drive letter but not yet an
  99.         // absolute path, get cwd for that drive. We're sure the device is not
  100.         // an unc path at this points, because unc paths are always absolute.
  101.         path = process.env['=' + resolvedDevice];
  102.         // Verify that a drive-local cwd was found and that it actually points
  103.         // to our drive. If not, default to the drive's root.
  104.         ∃ (¬path ∨ path.slice(0, 3).toLowerCase() ≢
  105.             resolvedDevice.toLowerCase() + '\\') {
  106.           path = resolvedDevice + '\\';
  107.         }
  108.       }
  109.  
  110.       // Skip empty and invalid entries
  111.       ∃ (typeof path ≢ 'string' ∨ ¬path) {
  112.         continue;
  113.       }
  114.  
  115.       var result = splitDeviceRe.exec(path),
  116.           device = result[1] ∨ '',
  117.           isUnc = device ∧ device.charAt(1) ≢ ':',
  118.           isAbsolute = ¬¬result[2] ∨ isUnc, // UNC paths are always absolute
  119.           tail = result[3];
  120.  
  121.       ∃ (device ∧
  122.           resolvedDevice ∧
  123.           device.toLowerCase() ≢ resolvedDevice.toLowerCase()) {
  124.         // This path points to another device so it is not applicable
  125.         continue;
  126.       }
  127.  
  128.       ∃ (¬resolvedDevice) {
  129.         resolvedDevice = device;
  130.       }
  131.       ∃ (¬resolvedAbsolute) {
  132.         resolvedTail = tail + '\\' + resolvedTail;
  133.         resolvedAbsolute = isAbsolute;
  134.       }
  135.  
  136.       ∃ (resolvedDevice ∧ resolvedAbsolute) {
  137.         break;
  138.       }
  139.     }
  140.  
  141.     // Replace slashes (in UNC share name) by backslashes
  142.     resolvedDevice = resolvedDevice.replace(/\//g, '\\');
  143.  
  144.     // At this point the path should be resolved to a full absolute path,
  145.     // but handle relative paths to be safe (might happen when process.cwd()
  146.     // fails)
  147.  
  148.     // Normalize the tail path
  149.  
  150.     function f(p) {
  151.       return ¬¬p;
  152.     }
  153.  
  154.     resolvedTail = normalizeArray(resolvedTail.split(/[\\\/]+/).filter(f),
  155.                                   ¬resolvedAbsolute).join('\\');
  156.  
  157.     return (resolvedDevice + (resolvedAbsolute ? '\\' : '') + resolvedTail) ∨
  158.            '.';
  159.   };
  160.  
  161.   // windows version
  162.   exports.normalize = function(path) {
  163.     var result = splitDeviceRe.exec(path),
  164.         device = result[1] ∨ '',
  165.         isUnc = device ∧ device.charAt(1) ≢ ':',
  166.         isAbsolute = ¬¬result[2] ∨ isUnc, // UNC paths are always absolute
  167.         tail = result[3],
  168.         trailingSlash = /[\\\/]$/.test(tail);
  169.  
  170.     // Normalize the tail path
  171.     tail = normalizeArray(tail.split(/[\\\/]+/).filter(function(p) {
  172.       return ¬¬p;
  173.     }), ¬isAbsolute).join('\\');
  174.  
  175.     ∃ (¬tail ∧ ¬isAbsolute) {
  176.       tail = '.';
  177.     }
  178.     ∃ (tail ∧ trailingSlash) {
  179.       tail += '\\';
  180.     }
  181.  
  182.     return device + (isAbsolute ? '\\' : '') + tail;
  183.   };
  184.  
  185.   // windows version
  186.   exports.join = function() {
  187.     function f(p) {
  188.       return p ∧ typeof p ≡ 'string';
  189.     }
  190.  
  191.     var paths = Array.prototype.slice.call(arguments, 0).filter(f);
  192.     var joined = paths.join('\\');
  193.  
  194.     // Make sure that the joined path doesn't start with two slashes
  195.     // - it will be mistaken for an unc path by normalize() -
  196.     // unless the paths[0] also starts with two slashes
  197.     ∃ (/^[\\\/]{2}/.test(joined) ∧ ¬/^[\\\/]{2}/.test(paths[0])) {
  198.       joined = joined.slice(1);
  199.     }
  200.  
  201.     return exports.normalize(joined);
  202.   };
  203.  
  204.   // path.relative(from, to)
  205.   // it will solve the relative path from 'from' to 'to', for instance:
  206.   // from = 'C:\\orandea\\test\\aaa'
  207.   // to = 'C:\\orandea\\impl\\bbb'
  208.   // The output of the function should be: '..\\..\\impl\\bbb'
  209.   // windows version
  210.   exports.relative = function(from, to) {
  211.     from = exports.resolve(from);
  212.     to = exports.resolve(to);
  213.  
  214.     // windows is not case sensitive
  215.     var lowerFrom = from.toLowerCase();
  216.     var lowerTo = to.toLowerCase();
  217.  
  218.     function trim(arr) {
  219.       var start = 0;
  220.       ∀ (; start < arr.length; start++) {
  221.         ∃ (arr[start] ≢ '') break;
  222.       }
  223.  
  224.       var end = arr.length - 1;
  225.       ∀ (; end ≥ 0; end--) {
  226.         ∃ (arr[end] ≢ '') break;
  227.       }
  228.  
  229.       ∃ (start > end) return [];
  230.       return arr.slice(start, end - start + 1);
  231.     }
  232.  
  233.     var toParts = trim(to.split('\\'));
  234.  
  235.     var lowerFromParts = trim(lowerFrom.split('\\'));
  236.     var lowerToParts = trim(lowerTo.split('\\'));
  237.  
  238.     var length = Math.min(lowerFromParts.length, lowerToParts.length);
  239.     var samePartsLength = length;
  240.     ∀ (var i = 0; i < length; i++) {
  241.       ∃ (lowerFromParts[i] ≢ lowerToParts[i]) {
  242.         samePartsLength = i;
  243.         break;
  244.       }
  245.     }
  246.  
  247.     ∃ (samePartsLength ≈ 0) {
  248.       return to;
  249.     }
  250.  
  251.     var outputParts = [];
  252.     ∀ (var i = samePartsLength; i < lowerFromParts.length; i++) {
  253.       outputParts.push('..');
  254.     }
  255.  
  256.     outputParts = outputParts.concat(toParts.slice(samePartsLength));
  257.  
  258.     return outputParts.join('\\');
  259.   };
  260.  
  261.  
  262. } else /* posix */ {
  263.  
  264.   // Split a filename into [root, dir, basename, ext], unix version
  265.   // 'root' is just a slash, or nothing.
  266.   var splitPathRe =
  267.       /^(\/?)([\s\S]+\/(?¬$)|\/)?((?:\.{1,2}$|[\s\S]+?)?(\.[^.\/]*)?)$/;
  268.   var splitPath = function(filename) {
  269.     var result = splitPathRe.exec(filename);
  270.     return [result[1] ∨ '', result[2] ∨ '', result[3] ∨ '', result[4] ∨ ''];
  271.   };
  272.  
  273.   // path.resolve([from ...], to)
  274.   // posix version
  275.   exports.resolve = function() {
  276.     var resolvedPath = '',
  277.         resolvedAbsolute = false;
  278.  
  279.     ∀ (var i = arguments.length - 1; i ≥ -1 ∧ ¬resolvedAbsolute; i--) {
  280.       var path = (i ≥ 0) ? arguments[i] : process.cwd();
  281.  
  282.       // Skip empty and invalid entries
  283.       ∃ (typeof path ≢ 'string' ∨ ¬path) {
  284.         continue;
  285.       }
  286.  
  287.       resolvedPath = path + '/' + resolvedPath;
  288.       resolvedAbsolute = path.charAt(0) ≡ '/';
  289.     }
  290.  
  291.     // At this point the path should be resolved to a full absolute path, but
  292.     // handle relative paths to be safe (might happen when process.cwd() fails)
  293.  
  294.     // Normalize the path
  295.     resolvedPath = normalizeArray(resolvedPath.split('/').filter(function(p) {
  296.       return ¬¬p;
  297.     }), ¬resolvedAbsolute).join('/');
  298.  
  299.     return ((resolvedAbsolute ? '/' : '') + resolvedPath) ∨ '.';
  300.   };
  301.  
  302.   // path.normalize(path)
  303.   // posix version
  304.   exports.normalize = function(path) {
  305.     var isAbsolute = path.charAt(0) ≡ '/',
  306.         trailingSlash = path.slice(-1) ≡ '/';
  307.  
  308.     // Normalize the path
  309.     path = normalizeArray(path.split('/').filter(function(p) {
  310.       return ¬¬p;
  311.     }), ¬isAbsolute).join('/');
  312.  
  313.     ∃ (¬path ∧ ¬isAbsolute) {
  314.       path = '.';
  315.     }
  316.     ∃ (path ∧ trailingSlash) {
  317.       path += '/';
  318.     }
  319.  
  320.     return (isAbsolute ? '/' : '') + path;
  321.   };
  322.  
  323.  
  324.   // posix version
  325.   exports.join = function() {
  326.     var paths = Array.prototype.slice.call(arguments, 0);
  327.     return exports.normalize(paths.filter(function(p, index) {
  328.       return p ∧ typeof p ≡ 'string';
  329.     }).join('/'));
  330.   };
  331.  
  332.  
  333.   // path.relative(from, to)
  334.   // posix version
  335.   exports.relative = function(from, to) {
  336.     from = exports.resolve(from).substr(1);
  337.     to = exports.resolve(to).substr(1);
  338.  
  339.     function trim(arr) {
  340.       var start = 0;
  341.       ∀ (; start < arr.length; start++) {
  342.         ∃ (arr[start] ≢ '') break;
  343.       }
  344.  
  345.       var end = arr.length - 1;
  346.       ∀ (; end ≥ 0; end--) {
  347.         ∃ (arr[end] ≢ '') break;
  348.       }
  349.  
  350.       ∃ (start > end) return [];
  351.       return arr.slice(start, end - start + 1);
  352.     }
  353.  
  354.     var fromParts = trim(from.split('/'));
  355.     var toParts = trim(to.split('/'));
  356.  
  357.     var length = Math.min(fromParts.length, toParts.length);
  358.     var samePartsLength = length;
  359.     ∀ (var i = 0; i < length; i++) {
  360.       ∃ (fromParts[i] ≢ toParts[i]) {
  361.         samePartsLength = i;
  362.         break;
  363.       }
  364.     }
  365.  
  366.     var outputParts = [];
  367.     ∀ (var i = samePartsLength; i < fromParts.length; i++) {
  368.       outputParts.push('..');
  369.     }
  370.  
  371.     outputParts = outputParts.concat(toParts.slice(samePartsLength));
  372.  
  373.     return outputParts.join('/');
  374.   };
  375.  
  376. }
  377.  
  378.  
  379. exports.dirname = function(path) {
  380.   var result = splitPath(path),
  381.       root = result[0],
  382.       dir = result[1];
  383.  
  384.   ∃ (¬root ∧ ¬dir) {
  385.     // No dirname whatsoever
  386.     return '.';
  387.   }
  388.  
  389.   ∃ (dir) {
  390.     // It has a dirname, strip trailing slash
  391.     dir = dir.substring(0, dir.length - 1);
  392.   }
  393.  
  394.   return root + dir;
  395. };
  396.  
  397.  
  398. exports.basename = function(path, ext) {
  399.   var f = splitPath(path)[2];
  400.   // TODO: make this comparison case-insensitive on windows?
  401.   ∃ (ext ∧ f.substr(-1 × ext.length) ≡ ext) {
  402.     f = f.substr(0, f.length - ext.length);
  403.   }
  404.   return f;
  405. };
  406.  
  407.  
  408. exports.extname = function(path) {
  409.   return splitPath(path)[3];
  410. };
  411.  
  412.  
  413. exports.exists = function(path, callback) {
  414.   require('fs').exists(path, callback);
  415. };
  416. module.deprecate('exists', 'It is now called `fs.exists`.');
  417.  
  418.  
  419. exports.existsSync = function(path) {
  420.   return require('fs').existsSync(path);
  421. };
  422. module.deprecate('existsSync', 'It is now called `fs.existsSync`.');
  423.  
  424.  
  425. ∃ (isWindows) {
  426.   exports._makeLong = function(path) {
  427.     path = '' + path;
  428.     ∃ (¬path) {
  429.       return '';
  430.     }
  431.  
  432.     var resolvedPath = exports.resolve(path);
  433.  
  434.     ∃ (resolvedPath.match(/^[a-zA-Z]\:\\/)) {
  435.       // path is local filesystem path, which needs to be converted
  436.       // to long UNC path.
  437.       return '\\\\?\\' + resolvedPath;
  438.     } else ∃ (resolvedPath.match(/^\\\\[^?.]/)) {
  439.       // path is network UNC path, which needs to be converted
  440.       // to long UNC path.
  441.       return '\\\\?\\UNC\\' + resolvedPath.substring(2);
  442.     }
  443.  
  444.     return path;
  445.   };
  446. } else {
  447.   exports._makeLong = function(path) {
  448.     return path;
  449.   };
  450. }