l0bsterssg

node.js static responsive blog post generator
Log | Files | Refs | README

old.js (8542B)


      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 var pathModule = require('path');
     23 var isWindows = process.platform === 'win32';
     24 var fs = require('fs');
     25 
     26 // JavaScript implementation of realpath, ported from node pre-v6
     27 
     28 var DEBUG = process.env.NODE_DEBUG && /fs/.test(process.env.NODE_DEBUG);
     29 
     30 function rethrow() {
     31   // Only enable in debug mode. A backtrace uses ~1000 bytes of heap space and
     32   // is fairly slow to generate.
     33   var callback;
     34   if (DEBUG) {
     35     var backtrace = new Error;
     36     callback = debugCallback;
     37   } else
     38     callback = missingCallback;
     39 
     40   return callback;
     41 
     42   function debugCallback(err) {
     43     if (err) {
     44       backtrace.message = err.message;
     45       err = backtrace;
     46       missingCallback(err);
     47     }
     48   }
     49 
     50   function missingCallback(err) {
     51     if (err) {
     52       if (process.throwDeprecation)
     53         throw err;  // Forgot a callback but don't know where? Use NODE_DEBUG=fs
     54       else if (!process.noDeprecation) {
     55         var msg = 'fs: missing callback ' + (err.stack || err.message);
     56         if (process.traceDeprecation)
     57           console.trace(msg);
     58         else
     59           console.error(msg);
     60       }
     61     }
     62   }
     63 }
     64 
     65 function maybeCallback(cb) {
     66   return typeof cb === 'function' ? cb : rethrow();
     67 }
     68 
     69 var normalize = pathModule.normalize;
     70 
     71 // Regexp that finds the next partion of a (partial) path
     72 // result is [base_with_slash, base], e.g. ['somedir/', 'somedir']
     73 if (isWindows) {
     74   var nextPartRe = /(.*?)(?:[\/\\]+|$)/g;
     75 } else {
     76   var nextPartRe = /(.*?)(?:[\/]+|$)/g;
     77 }
     78 
     79 // Regex to find the device root, including trailing slash. E.g. 'c:\\'.
     80 if (isWindows) {
     81   var splitRootRe = /^(?:[a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?[\\\/]*/;
     82 } else {
     83   var splitRootRe = /^[\/]*/;
     84 }
     85 
     86 exports.realpathSync = function realpathSync(p, cache) {
     87   // make p is absolute
     88   p = pathModule.resolve(p);
     89 
     90   if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
     91     return cache[p];
     92   }
     93 
     94   var original = p,
     95       seenLinks = {},
     96       knownHard = {};
     97 
     98   // current character position in p
     99   var pos;
    100   // the partial path so far, including a trailing slash if any
    101   var current;
    102   // the partial path without a trailing slash (except when pointing at a root)
    103   var base;
    104   // the partial path scanned in the previous round, with slash
    105   var previous;
    106 
    107   start();
    108 
    109   function start() {
    110     // Skip over roots
    111     var m = splitRootRe.exec(p);
    112     pos = m[0].length;
    113     current = m[0];
    114     base = m[0];
    115     previous = '';
    116 
    117     // On windows, check that the root exists. On unix there is no need.
    118     if (isWindows && !knownHard[base]) {
    119       fs.lstatSync(base);
    120       knownHard[base] = true;
    121     }
    122   }
    123 
    124   // walk down the path, swapping out linked pathparts for their real
    125   // values
    126   // NB: p.length changes.
    127   while (pos < p.length) {
    128     // find the next part
    129     nextPartRe.lastIndex = pos;
    130     var result = nextPartRe.exec(p);
    131     previous = current;
    132     current += result[0];
    133     base = previous + result[1];
    134     pos = nextPartRe.lastIndex;
    135 
    136     // continue if not a symlink
    137     if (knownHard[base] || (cache && cache[base] === base)) {
    138       continue;
    139     }
    140 
    141     var resolvedLink;
    142     if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
    143       // some known symbolic link.  no need to stat again.
    144       resolvedLink = cache[base];
    145     } else {
    146       var stat = fs.lstatSync(base);
    147       if (!stat.isSymbolicLink()) {
    148         knownHard[base] = true;
    149         if (cache) cache[base] = base;
    150         continue;
    151       }
    152 
    153       // read the link if it wasn't read before
    154       // dev/ino always return 0 on windows, so skip the check.
    155       var linkTarget = null;
    156       if (!isWindows) {
    157         var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
    158         if (seenLinks.hasOwnProperty(id)) {
    159           linkTarget = seenLinks[id];
    160         }
    161       }
    162       if (linkTarget === null) {
    163         fs.statSync(base);
    164         linkTarget = fs.readlinkSync(base);
    165       }
    166       resolvedLink = pathModule.resolve(previous, linkTarget);
    167       // track this, if given a cache.
    168       if (cache) cache[base] = resolvedLink;
    169       if (!isWindows) seenLinks[id] = linkTarget;
    170     }
    171 
    172     // resolve the link, then start over
    173     p = pathModule.resolve(resolvedLink, p.slice(pos));
    174     start();
    175   }
    176 
    177   if (cache) cache[original] = p;
    178 
    179   return p;
    180 };
    181 
    182 
    183 exports.realpath = function realpath(p, cache, cb) {
    184   if (typeof cb !== 'function') {
    185     cb = maybeCallback(cache);
    186     cache = null;
    187   }
    188 
    189   // make p is absolute
    190   p = pathModule.resolve(p);
    191 
    192   if (cache && Object.prototype.hasOwnProperty.call(cache, p)) {
    193     return process.nextTick(cb.bind(null, null, cache[p]));
    194   }
    195 
    196   var original = p,
    197       seenLinks = {},
    198       knownHard = {};
    199 
    200   // current character position in p
    201   var pos;
    202   // the partial path so far, including a trailing slash if any
    203   var current;
    204   // the partial path without a trailing slash (except when pointing at a root)
    205   var base;
    206   // the partial path scanned in the previous round, with slash
    207   var previous;
    208 
    209   start();
    210 
    211   function start() {
    212     // Skip over roots
    213     var m = splitRootRe.exec(p);
    214     pos = m[0].length;
    215     current = m[0];
    216     base = m[0];
    217     previous = '';
    218 
    219     // On windows, check that the root exists. On unix there is no need.
    220     if (isWindows && !knownHard[base]) {
    221       fs.lstat(base, function(err) {
    222         if (err) return cb(err);
    223         knownHard[base] = true;
    224         LOOP();
    225       });
    226     } else {
    227       process.nextTick(LOOP);
    228     }
    229   }
    230 
    231   // walk down the path, swapping out linked pathparts for their real
    232   // values
    233   function LOOP() {
    234     // stop if scanned past end of path
    235     if (pos >= p.length) {
    236       if (cache) cache[original] = p;
    237       return cb(null, p);
    238     }
    239 
    240     // find the next part
    241     nextPartRe.lastIndex = pos;
    242     var result = nextPartRe.exec(p);
    243     previous = current;
    244     current += result[0];
    245     base = previous + result[1];
    246     pos = nextPartRe.lastIndex;
    247 
    248     // continue if not a symlink
    249     if (knownHard[base] || (cache && cache[base] === base)) {
    250       return process.nextTick(LOOP);
    251     }
    252 
    253     if (cache && Object.prototype.hasOwnProperty.call(cache, base)) {
    254       // known symbolic link.  no need to stat again.
    255       return gotResolvedLink(cache[base]);
    256     }
    257 
    258     return fs.lstat(base, gotStat);
    259   }
    260 
    261   function gotStat(err, stat) {
    262     if (err) return cb(err);
    263 
    264     // if not a symlink, skip to the next path part
    265     if (!stat.isSymbolicLink()) {
    266       knownHard[base] = true;
    267       if (cache) cache[base] = base;
    268       return process.nextTick(LOOP);
    269     }
    270 
    271     // stat & read the link if not read before
    272     // call gotTarget as soon as the link target is known
    273     // dev/ino always return 0 on windows, so skip the check.
    274     if (!isWindows) {
    275       var id = stat.dev.toString(32) + ':' + stat.ino.toString(32);
    276       if (seenLinks.hasOwnProperty(id)) {
    277         return gotTarget(null, seenLinks[id], base);
    278       }
    279     }
    280     fs.stat(base, function(err) {
    281       if (err) return cb(err);
    282 
    283       fs.readlink(base, function(err, target) {
    284         if (!isWindows) seenLinks[id] = target;
    285         gotTarget(err, target);
    286       });
    287     });
    288   }
    289 
    290   function gotTarget(err, target, base) {
    291     if (err) return cb(err);
    292 
    293     var resolvedLink = pathModule.resolve(previous, target);
    294     if (cache) cache[base] = resolvedLink;
    295     gotResolvedLink(resolvedLink);
    296   }
    297 
    298   function gotResolvedLink(resolvedLink) {
    299     // resolve the link, then start over
    300     p = pathModule.resolve(resolvedLink, p.slice(pos));
    301     start();
    302   }
    303 };