Name: js-handler/node_modules/nodeunit/node_modules/tap/node_modules/glob/glob.js 
1:
// Approach:
2:
//
3:
// 1. Get the minimatch set
4:
// 2. For each pattern in the set, PROCESS(pattern)
5:
// 3. Store matches per-set, then uniq them
6:
//
7:
// PROCESS(pattern)
8:
// Get the first [n] items from pattern that are all strings
9:
// Join these together.  This is PREFIX.
10:
//   If there is no more remaining, then stat(PREFIX) and
11:
//   add to matches if it succeeds.  END.
12:
// readdir(PREFIX) as ENTRIES
13:
//   If fails, END
14:
//   If pattern[n] is GLOBSTAR
15:
//     // handle the case where the globstar match is empty
16:
//     // by pruning it out, and testing the resulting pattern
17:
//     PROCESS(pattern[0..n] + pattern[n+1 .. $])
18:
//     // handle other cases.
19:
//     for ENTRY in ENTRIES (not dotfiles)
20:
//       // attach globstar + tail onto the entry
21:
//       PROCESS(pattern[0..n] + ENTRY + pattern[n .. $])
22:
//
23:
//   else // not globstar
24:
//     for ENTRY in ENTRIES (not dotfiles, unless pattern[n] is dot)
25:
//       Test ENTRY against pattern[n]
26:
//       If fails, continue
27:
//       If passes, PROCESS(pattern[0..n] + item + pattern[n+1 .. $])
28:
//
29:
// Caveat:
30:
//   Cache all stats and readdirs results to minimize syscall.  Since all
31:
//   we ever care about is existence and directory-ness, we can just keep
32:
//   `true` for files, and [children,...] for directories, or `false` for
33:
//   things that don't exist.
34:
 
35:
 
36:
 
37:
module.exports = glob
38:
 
39:
var fs = require("fs")
40:
, minimatch = require("minimatch")
41:
, Minimatch = minimatch.Minimatch
42:
, inherits = require("inherits")
43:
, EE = require("events").EventEmitter
44:
, path = require("path")
45:
, isDir = {}
46:
, assert = require("assert").ok
47:
 
48:
function glob (pattern, options, cb) {
49:
  if (typeof options === "function") cb = options, options = {}
50:
  if (!options) options = {}
51:
 
52:
  if (typeof options === "number") {
53:
    deprecated()
54:
    return
55:
  }
56:
 
57:
  var g = new Glob(pattern, options, cb)
58:
  return g.sync ? g.found : g
59:
}
60:
 
61:
glob.fnmatch = deprecated
62:
 
63:
function deprecated () {
64:
  throw new Error("glob's interface has changed. Please see the docs.")
65:
}
66:
 
67:
glob.sync = globSync
68:
function globSync (pattern, options) {
69:
  if (typeof options === "number") {
70:
    deprecated()
71:
    return
72:
  }
73:
 
74:
  options = options || {}
75:
  options.sync = true
76:
  return glob(pattern, options)
77:
}
78:
 
79:
 
80:
glob.Glob = Glob
81:
inherits(Glob, EE)
82:
function Glob (pattern, options, cb) {
83:
  if (!(this instanceof Glob)) {
84:
    return new Glob(pattern, options, cb)
85:
  }
86:
 
87:
  if (typeof cb === "function") {
88:
    this.on("error", cb)
89:
    this.on("end", function (matches) {
90:
      cb(null, matches)
91:
    })
92:
  }
93:
 
94:
  options = options || {}
95:
 
96:
  this.EOF = {}
97:
  this._emitQueue = []
98:
 
99:
  this.maxDepth = options.maxDepth || 1000
100:
  this.maxLength = options.maxLength || Infinity
101:
  this.cache = options.cache || {}
102:
  this.statCache = options.statCache || {}
103:
 
104:
  this.changedCwd = false
105:
  var cwd = process.cwd()
106:
  if (!options.hasOwnProperty("cwd")) this.cwd = cwd
107:
  else {
108:
    this.cwd = options.cwd
109:
    this.changedCwd = path.resolve(options.cwd) !== cwd
110:
  }
111:
 
112:
  this.root = options.root || path.resolve(this.cwd, "/")
113:
  this.root = path.resolve(this.root)
114:
  if (process.platform === "win32")
115:
    this.root = this.root.replace(/\\/g, "/")
116:
 
117:
  this.nomount = !!options.nomount
118:
 
119:
  if (!pattern) {
120:
    throw new Error("must provide pattern")
121:
  }
122:
 
123:
  // base-matching: just use globstar for that.
124:
  if (options.matchBase && -1 === pattern.indexOf("/")) {
125:
    if (options.noglobstar) {
126:
      throw new Error("base matching requires globstar")
127:
    }
128:
    pattern = "**/" + pattern
129:
  }
130:
 
131:
  this.strict = options.strict !== false
132:
  this.dot = !!options.dot
133:
  this.mark = !!options.mark
134:
  this.sync = !!options.sync
135:
  this.nounique = !!options.nounique
136:
  this.nonull = !!options.nonull
137:
  this.nosort = !!options.nosort
138:
  this.nocase = !!options.nocase
139:
  this.stat = !!options.stat
140:
 
141:
  this.debug = !!options.debug || !!options.globDebug
142:
  if (this.debug)
143:
    this.log = console.error
144:
 
145:
  this.silent = !!options.silent
146:
 
147:
  var mm = this.minimatch = new Minimatch(pattern, options)
148:
  this.options = mm.options
149:
  pattern = this.pattern = mm.pattern
150:
 
151:
  this.error = null
152:
  this.aborted = false
153:
 
154:
  // list of all the patterns that ** has resolved do, so
155:
  // we can avoid visiting multiple times.
156:
  this._globstars = {}
157:
 
158:
  EE.call(this)
159:
 
160:
  // process each pattern in the minimatch set
161:
  var n = this.minimatch.set.length
162:
 
163:
  // The matches are stored as {<filename>: true,...} so that
164:
  // duplicates are automagically pruned.
165:
  // Later, we do an Object.keys() on these.
166:
  // Keep them as a list so we can fill in when nonull is set.
167:
  this.matches = new Array(n)
168:
 
169:
  this.minimatch.set.forEach(iterator.bind(this))
170:
  function iterator (pattern, i, set) {
171:
    this._process(pattern, 0, i, function (er) {
172:
      if (er) this.emit("error", er)
173:
      if (-- n <= 0) this._finish()
174:
    })
175:
  }
176:
}
177:
 
178:
Glob.prototype.log = function () {}
179:
 
180:
Glob.prototype._finish = function () {
181:
  assert(this instanceof Glob)
182:
 
183:
  var nou = this.nounique
184:
  , all = nou ? [] : {}
185:
 
186:
  for (var i = 0, l = this.matches.length; i < l; i ++) {
187:
    var matches = this.matches[i]
188:
    this.log("matches[%d] =", i, matches)
189:
    // do like the shell, and spit out the literal glob
190:
    if (!matches) {
191:
      if (this.nonull) {
192:
        var literal = this.minimatch.globSet[i]
193:
        if (nou) all.push(literal)
194:
        else all[literal] = true
195:
      }
196:
    } else {
197:
      // had matches
198:
      var m = Object.keys(matches)
199:
      if (nou) all.push.apply(all, m)
200:
      else m.forEach(function (m) {
201:
        all[m] = true
202:
      })
203:
    }
204:
  }
205:
 
206:
  if (!nou) all = Object.keys(all)
207:
 
208:
  if (!this.nosort) {
209:
    all = all.sort(this.nocase ? alphasorti : alphasort)
210:
  }
211:
 
212:
  if (this.mark) {
213:
    // at *some* point we statted all of these
214:
    all = all.map(function (m) {
215:
      var sc = this.cache[m]
216:
      if (!sc)
217:
        return m
218:
      var isDir = (Array.isArray(sc) || sc === 2)
219:
      if (isDir && m.slice(-1) !== "/") {
220:
        return m + "/"
221:
      }
222:
      if (!isDir && m.slice(-1) === "/") {
223:
        return m.replace(/\/+$/, "")
224:
      }
225:
      return m
226:
    }, this)
227:
  }
228:
 
229:
  this.log("emitting end", all)
230:
 
231:
  this.EOF = this.found = all
232:
  this.emitMatch(this.EOF)
233:
}
234:
 
235:
function alphasorti (a, b) {
236:
  a = a.toLowerCase()
237:
  b = b.toLowerCase()
238:
  return alphasort(a, b)
239:
}
240:
 
241:
function alphasort (a, b) {
242:
  return a > b ? 1 : a < b ? -1 : 0
243:
}
244:
 
245:
Glob.prototype.abort = function () {
246:
  this.aborted = true
247:
  this.emit("abort")
248:
}
249:
 
250:
Glob.prototype.pause = function () {
251:
  if (this.paused) return
252:
  if (this.sync)
253:
    this.emit("error", new Error("Can't pause/resume sync glob"))
254:
  this.paused = true
255:
  this.emit("pause")
256:
}
257:
 
258:
Glob.prototype.resume = function () {
259:
  if (!this.paused) return
260:
  if (this.sync)
261:
    this.emit("error", new Error("Can't pause/resume sync glob"))
262:
  this.paused = false
263:
  this.emit("resume")
264:
  this._processEmitQueue()
265:
  //process.nextTick(this.emit.bind(this, "resume"))
266:
}
267:
 
268:
Glob.prototype.emitMatch = function (m) {
269:
  if (!this.stat || this.statCache[m] || m === this.EOF) {
270:
    this._emitQueue.push(m)
271:
    this._processEmitQueue()
272:
  } else {
273:
    this._stat(m, function(exists, isDir) {
274:
      if (exists) {
275:
        this._emitQueue.push(m)
276:
        this._processEmitQueue()
277:
      }
278:
    })
279:
  }
280:
}
281:
 
282:
Glob.prototype._processEmitQueue = function (m) {
283:
  while (!this._processingEmitQueue &&
284:
         !this.paused) {
285:
    this._processingEmitQueue = true
286:
    var m = this._emitQueue.shift()
287:
    if (!m) {
288:
      this._processingEmitQueue = false
289:
      break
290:
    }
291:
 
292:
    this.log('emit!', m === this.EOF ? "end" : "match")
293:
 
294:
    this.emit(m === this.EOF ? "end" : "match", m)
295:
    this._processingEmitQueue = false
296:
  }
297:
}
298:
 
299:
Glob.prototype._process = function (pattern, depth, index, cb_) {
300:
  assert(this instanceof Glob)
301:
 
302:
  var cb = function cb (er, res) {
303:
    assert(this instanceof Glob)
304:
    if (this.paused) {
305:
      if (!this._processQueue) {
306:
        this._processQueue = []
307:
        this.once("resume", function () {
308:
          var q = this._processQueue
309:
          this._processQueue = null
310:
          q.forEach(function (cb) { cb() })
311:
        })
312:
      }
313:
      this._processQueue.push(cb_.bind(this, er, res))
314:
    } else {
315:
      cb_.call(this, er, res)
316:
    }
317:
  }.bind(this)
318:
 
319:
  if (this.aborted) return cb()
320:
 
321:
  if (depth > this.maxDepth) return cb()
322:
 
323:
  // Get the first [n] parts of pattern that are all strings.
324:
  var n = 0
325:
  while (typeof pattern[n] === "string") {
326:
    n ++
327:
  }
328:
  // now n is the index of the first one that is *not* a string.
329:
 
330:
  // see if there's anything else
331:
  var prefix
332:
  switch (n) {
333:
    // if not, then this is rather simple
334:
    case pattern.length:
335:
      prefix = pattern.join("/")
336:
      this._stat(prefix, function (exists, isDir) {
337:
        // either it's there, or it isn't.
338:
        // nothing more to do, either way.
339:
        if (exists) {
340:
          if (prefix && isAbsolute(prefix) && !this.nomount) {
341:
            if (prefix.charAt(0) === "/") {
342:
              prefix = path.join(this.root, prefix)
343:
            } else {
344:
              prefix = path.resolve(this.root, prefix)
345:
            }
346:
          }
347:
 
348:
          if (process.platform === "win32")
349:
            prefix = prefix.replace(/\\/g, "/")
350:
 
351:
          this.matches[index] = this.matches[index] || {}
352:
          this.matches[index][prefix] = true
353:
          this.emitMatch(prefix)
354:
        }
355:
        return cb()
356:
      })
357:
      return
358:
 
359:
    case 0:
360:
      // pattern *starts* with some non-trivial item.
361:
      // going to readdir(cwd), but not include the prefix in matches.
362:
      prefix = null
363:
      break
364:
 
365:
    default:
366:
      // pattern has some string bits in the front.
367:
      // whatever it starts with, whether that's "absolute" like /foo/bar,
368:
      // or "relative" like "../baz"
369:
      prefix = pattern.slice(0, n)
370:
      prefix = prefix.join("/")
371:
      break
372:
  }
373:
 
374:
  // get the list of entries.
375:
  var read
376:
  if (prefix === null) read = "."
377:
  else if (isAbsolute(prefix) || isAbsolute(pattern.join("/"))) {
378:
    if (!prefix || !isAbsolute(prefix)) {
379:
      prefix = path.join("/", prefix)
380:
    }
381:
    read = prefix = path.resolve(prefix)
382:
 
383:
    // if (process.platform === "win32")
384:
    //   read = prefix = prefix.replace(/^[a-zA-Z]:|\\/g, "/")
385:
 
386:
    this.log('absolute: ', prefix, this.root, pattern, read)
387:
  } else {
388:
    read = prefix
389:
  }
390:
 
391:
  this.log('readdir(%j)', read, this.cwd, this.root)
392:
 
393:
  return this._readdir(read, function (er, entries) {
394:
    if (er) {
395:
      // not a directory!
396:
      // this means that, whatever else comes after this, it can never match
397:
      return cb()
398:
    }
399:
 
400:
    // globstar is special
401:
    if (pattern[n] === minimatch.GLOBSTAR) {
402:
      // test without the globstar, and with every child both below
403:
      // and replacing the globstar.
404:
      var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
405:
      entries.forEach(function (e) {
406:
        if (e.charAt(0) === "." && !this.dot) return
407:
        // instead of the globstar
408:
        s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
409:
        // below the globstar
410:
        s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
411:
      }, this)
412:
 
413:
      s = s.filter(function (pattern) {
414:
        var key = gsKey(pattern)
415:
        var seen = !this._globstars[key]
416:
        this._globstars[key] = true
417:
        return seen
418:
      }, this)
419:
 
420:
      if (!s.length)
421:
        return cb()
422:
 
423:
      // now asyncForEach over this
424:
      var l = s.length
425:
      , errState = null
426:
      s.forEach(function (gsPattern) {
427:
        this._process(gsPattern, depth + 1, index, function (er) {
428:
          if (errState) return
429:
          if (er) return cb(errState = er)
430:
          if (--l <= 0) return cb()
431:
        })
432:
      }, this)
433:
 
434:
      return
435:
    }
436:
 
437:
    // not a globstar
438:
    // It will only match dot entries if it starts with a dot, or if
439:
    // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
440:
    var pn = pattern[n]
441:
    var rawGlob = pattern[n]._glob
442:
    , dotOk = this.dot || rawGlob.charAt(0) === "."
443:
 
444:
    entries = entries.filter(function (e) {
445:
      return (e.charAt(0) !== "." || dotOk) &&
446:
             e.match(pattern[n])
447:
    })
448:
 
449:
    // If n === pattern.length - 1, then there's no need for the extra stat
450:
    // *unless* the user has specified "mark" or "stat" explicitly.
451:
    // We know that they exist, since the readdir returned them.
452:
    if (n === pattern.length - 1 &&
453:
        !this.mark &&
454:
        !this.stat) {
455:
      entries.forEach(function (e) {
456:
        if (prefix) {
457:
          if (prefix !== "/") e = prefix + "/" + e
458:
          else e = prefix + e
459:
        }
460:
        if (e.charAt(0) === "/" && !this.nomount) {
461:
          e = path.join(this.root, e)
462:
        }
463:
 
464:
        if (process.platform === "win32")
465:
          e = e.replace(/\\/g, "/")
466:
 
467:
        this.matches[index] = this.matches[index] || {}
468:
        this.matches[index][e] = true
469:
        this.emitMatch(e)
470:
      }, this)
471:
      return cb.call(this)
472:
    }
473:
 
474:
 
475:
    // now test all the remaining entries as stand-ins for that part
476:
    // of the pattern.
477:
    var l = entries.length
478:
    , errState = null
479:
    if (l === 0) return cb() // no matches possible
480:
    entries.forEach(function (e) {
481:
      var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
482:
      this._process(p, depth + 1, index, function (er) {
483:
        if (errState) return
484:
        if (er) return cb(errState = er)
485:
        if (--l === 0) return cb.call(this)
486:
      })
487:
    }, this)
488:
  })
489:
 
490:
}
491:
 
492:
function gsKey (pattern) {
493:
  return '**' + pattern.map(function (p) {
494:
    return (p === minimatch.GLOBSTAR) ? '**' : (''+p)
495:
  }).join('/')
496:
}
497:
 
498:
Glob.prototype._stat = function (f, cb) {
499:
  assert(this instanceof Glob)
500:
  var abs = f
501:
  if (f.charAt(0) === "/") {
502:
    abs = path.join(this.root, f)
503:
  } else if (this.changedCwd) {
504:
    abs = path.resolve(this.cwd, f)
505:
  }
506:
 
507:
  if (f.length > this.maxLength) {
508:
    var er = new Error("Path name too long")
509:
    er.code = "ENAMETOOLONG"
510:
    er.path = f
511:
    return this._afterStat(f, abs, cb, er)
512:
  }
513:
 
514:
  this.log('stat', [this.cwd, f, '=', abs])
515:
 
516:
  if (!this.stat && this.cache.hasOwnProperty(f)) {
517:
    var exists = this.cache[f]
518:
    , isDir = exists && (Array.isArray(exists) || exists === 2)
519:
    if (this.sync) return cb.call(this, !!exists, isDir)
520:
    return process.nextTick(cb.bind(this, !!exists, isDir))
521:
  }
522:
 
523:
  var stat = this.statCache[abs]
524:
  if (this.sync || stat) {
525:
    var er
526:
    try {
527:
      stat = fs.statSync(abs)
528:
    } catch (e) {
529:
      er = e
530:
    }
531:
    this._afterStat(f, abs, cb, er, stat)
532:
  } else {
533:
    fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
534:
  }
535:
}
536:
 
537:
Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
538:
  var exists
539:
  assert(this instanceof Glob)
540:
 
541:
  if (abs.slice(-1) === "/" && stat && !stat.isDirectory()) {
542:
    this.log("should be ENOTDIR, fake it")
543:
 
544:
    er = new Error("ENOTDIR, not a directory '" + abs + "'")
545:
    er.path = abs
546:
    er.code = "ENOTDIR"
547:
    stat = null
548:
  }
549:
 
550:
  var emit = !this.statCache[abs]
551:
  this.statCache[abs] = stat
552:
 
553:
  if (er || !stat) {
554:
    exists = false
555:
  } else {
556:
    exists = stat.isDirectory() ? 2 : 1
557:
    if (emit)
558:
      this.emit('stat', f, stat)
559:
  }
560:
  this.cache[f] = this.cache[f] || exists
561:
  cb.call(this, !!exists, exists === 2)
562:
}
563:
 
564:
Glob.prototype._readdir = function (f, cb) {
565:
  assert(this instanceof Glob)
566:
  var abs = f
567:
  if (f.charAt(0) === "/") {
568:
    abs = path.join(this.root, f)
569:
  } else if (isAbsolute(f)) {
570:
    abs = f
571:
  } else if (this.changedCwd) {
572:
    abs = path.resolve(this.cwd, f)
573:
  }
574:
 
575:
  if (f.length > this.maxLength) {
576:
    var er = new Error("Path name too long")
577:
    er.code = "ENAMETOOLONG"
578:
    er.path = f
579:
    return this._afterReaddir(f, abs, cb, er)
580:
  }
581:
 
582:
  this.log('readdir', [this.cwd, f, abs])
583:
  if (this.cache.hasOwnProperty(f)) {
584:
    var c = this.cache[f]
585:
    if (Array.isArray(c)) {
586:
      if (this.sync) return cb.call(this, null, c)
587:
      return process.nextTick(cb.bind(this, null, c))
588:
    }
589:
 
590:
    if (!c || c === 1) {
591:
      // either ENOENT or ENOTDIR
592:
      var code = c ? "ENOTDIR" : "ENOENT"
593:
      , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
594:
      er.path = f
595:
      er.code = code
596:
      this.log(f, er)
597:
      if (this.sync) return cb.call(this, er)
598:
      return process.nextTick(cb.bind(this, er))
599:
    }
600:
 
601:
    // at this point, c === 2, meaning it's a dir, but we haven't
602:
    // had to read it yet, or c === true, meaning it's *something*
603:
    // but we don't have any idea what.  Need to read it, either way.
604:
  }
605:
 
606:
  if (this.sync) {
607:
    var er, entries
608:
    try {
609:
      entries = fs.readdirSync(abs)
610:
    } catch (e) {
611:
      er = e
612:
    }
613:
    return this._afterReaddir(f, abs, cb, er, entries)
614:
  }
615:
 
616:
  fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
617:
}
618:
 
619:
Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
620:
  assert(this instanceof Glob)
621:
  if (entries && !er) {
622:
    this.cache[f] = entries
623:
    // if we haven't asked to stat everything for suresies, then just
624:
    // assume that everything in there exists, so we can avoid
625:
    // having to stat it a second time.  This also gets us one step
626:
    // further into ELOOP territory.
627:
    if (!this.mark && !this.stat) {
628:
      entries.forEach(function (e) {
629:
        if (f === "/") e = f + e
630:
        else e = f + "/" + e
631:
        this.cache[e] = true
632:
      }, this)
633:
    }
634:
 
635:
    return cb.call(this, er, entries)
636:
  }
637:
 
638:
  // now handle errors, and cache the information
639:
  if (er) switch (er.code) {
640:
    case "ENOTDIR": // totally normal. means it *does* exist.
641:
      this.cache[f] = 1
642:
      return cb.call(this, er)
643:
    case "ENOENT": // not terribly unusual
644:
    case "ELOOP":
645:
    case "ENAMETOOLONG":
646:
    case "UNKNOWN":
647:
      this.cache[f] = false
648:
      return cb.call(this, er)
649:
    default: // some unusual error.  Treat as failure.
650:
      this.cache[f] = false
651:
      if (this.strict) this.emit("error", er)
652:
      if (!this.silent) console.error("glob error", er)
653:
      return cb.call(this, er)
654:
  }
655:
}
656:
 
657:
var isAbsolute = process.platform === "win32" ? absWin : absUnix
658:
 
659:
function absWin (p) {
660:
  if (absUnix(p)) return true
661:
  // pull off the device/UNC bit from a windows path.
662:
  // from node's lib/path.js
663:
  var splitDeviceRe =
664:
      /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/]+[^\\\/]+)?([\\\/])?([\s\S]*?)$/
665:
    , result = splitDeviceRe.exec(p)
666:
    , device = result[1] || ''
667:
    , isUnc = device && device.charAt(1) !== ':'
668:
    , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
669:
 
670:
  return isAbsolute
671:
}
672:
 
673:
function absUnix (p) {
674:
  return p.charAt(0) === "/" || p === ""
675:
}