Tizen 2.0 Release
[platform/framework/web/web-ui-fw.git] / libs / js / jquery-mobile-1.2.0 / node_modules / grunt / node_modules / jshint / node_modules / cli / 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+1]
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("graceful-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       // console.error("cb with matches", matches)
91       cb(null, matches)
92     })
93   }
94
95   options = options || {}
96
97   this.EOF = {}
98   this._emitQueue = []
99
100   this.maxDepth = options.maxDepth || 1000
101   this.maxLength = options.maxLength || Infinity
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
115   this.nomount = !!options.nomount
116
117   if (!pattern) {
118     throw new Error("must provide pattern")
119   }
120
121   // base-matching: just use globstar for that.
122   if (options.matchBase && -1 === pattern.indexOf("/")) {
123     if (options.noglobstar) {
124       throw new Error("base matching requires globstar")
125     }
126     pattern = "**/" + pattern
127   }
128
129   this.dot = !!options.dot
130   this.mark = !!options.mark
131   this.sync = !!options.sync
132   this.nounique = !!options.nounique
133   this.nonull = !!options.nonull
134   this.nosort = !!options.nosort
135   this.nocase = !!options.nocase
136   this.stat = !!options.stat
137   this.debug = !!options.debug || !!options.globDebug
138   this.silent = !!options.silent
139
140   var mm = this.minimatch = new Minimatch(pattern, options)
141   this.options = mm.options
142   pattern = this.pattern = mm.pattern
143
144   this.error = null
145   this.aborted = false
146
147   EE.call(this)
148
149   // process each pattern in the minimatch set
150   var n = this.minimatch.set.length
151
152   // The matches are stored as {<filename>: true,...} so that
153   // duplicates are automagically pruned.
154   // Later, we do an Object.keys() on these.
155   // Keep them as a list so we can fill in when nonull is set.
156   this.matches = new Array(n)
157
158   this.minimatch.set.forEach(iterator.bind(this))
159   function iterator (pattern, i, set) {
160     this._process(pattern, 0, i, function (er) {
161       if (er) this.emit("error", er)
162       if (-- n <= 0) this._finish()
163     })
164   }
165 }
166
167 Glob.prototype._finish = function () {
168   assert(this instanceof Glob)
169
170   var nou = this.nounique
171   , all = nou ? [] : {}
172
173   for (var i = 0, l = this.matches.length; i < l; i ++) {
174     var matches = this.matches[i]
175     if (this.debug) console.error("matches[%d] =", i, matches)
176     // do like the shell, and spit out the literal glob
177     if (!matches) {
178       if (this.nonull) {
179         var literal = this.minimatch.globSet[i]
180         if (nou) all.push(literal)
181         else all[literal] = true
182       }
183     } else {
184       // had matches
185       var m = Object.keys(matches)
186       if (nou) all.push.apply(all, m)
187       else m.forEach(function (m) {
188         all[m] = true
189       })
190     }
191   }
192
193   if (!nou) all = Object.keys(all)
194
195   if (!this.nosort) {
196     all = all.sort(this.nocase ? alphasorti : alphasort)
197   }
198
199   if (this.mark) {
200     // at *some* point we statted all of these
201     all = all.map(function (m) {
202       var sc = this.statCache[m]
203       if (!sc)
204         return m
205       var isDir = (Array.isArray(sc) || sc === 2)
206       if (isDir && m.slice(-1) !== "/") {
207         return m + "/"
208       }
209       if (!isDir && m.slice(-1) === "/") {
210         return m.replace(/\/+$/, "")
211       }
212       return m
213     }, this)
214   }
215
216   if (this.debug) console.error("emitting end", all)
217
218   this.EOF = this.found = all
219   this.emitMatch(this.EOF)
220 }
221
222 function alphasorti (a, b) {
223   a = a.toLowerCase()
224   b = b.toLowerCase()
225   return alphasort(a, b)
226 }
227
228 function alphasort (a, b) {
229   return a > b ? 1 : a < b ? -1 : 0
230 }
231
232 Glob.prototype.abort = function () {
233   this.aborted = true
234   this.emit("abort")
235 }
236
237 Glob.prototype.pause = function () {
238   if (this.paused) return
239   if (this.sync)
240     this.emit("error", new Error("Can't pause/resume sync glob"))
241   this.paused = true
242   this.emit("pause")
243 }
244
245 Glob.prototype.resume = function () {
246   if (!this.paused) return
247   if (this.sync)
248     this.emit("error", new Error("Can't pause/resume sync glob"))
249   this.paused = false
250   this.emit("resume")
251   this._processEmitQueue()
252   //process.nextTick(this.emit.bind(this, "resume"))
253 }
254
255 Glob.prototype.emitMatch = function (m) {
256   this._emitQueue.push(m)
257   this._processEmitQueue()
258 }
259
260 Glob.prototype._processEmitQueue = function (m) {
261   while (!this._processingEmitQueue &&
262          !this.paused) {
263     this._processingEmitQueue = true
264     var m = this._emitQueue.shift()
265     if (!m) {
266       this._processingEmitQueue = false
267       break
268     }
269     if (this.debug) {
270       console.error('emit!', m === this.EOF ? "end" : "match")
271     }
272     this.emit(m === this.EOF ? "end" : "match", m)
273     this._processingEmitQueue = false
274   }
275 }
276
277 Glob.prototype._process = function (pattern, depth, index, cb_) {
278   assert(this instanceof Glob)
279
280   var cb = function cb (er, res) {
281     assert(this instanceof Glob)
282     if (this.paused) {
283       if (!this._processQueue) {
284         this._processQueue = []
285         this.once("resume", function () {
286           var q = this._processQueue
287           this._processQueue = null
288           q.forEach(function (cb) { cb() })
289         })
290       }
291       this._processQueue.push(cb_.bind(this, er, res))
292     } else {
293       cb_.call(this, er, res)
294     }
295   }.bind(this)
296
297   if (this.aborted) return cb()
298
299   if (depth > this.maxDepth) return cb()
300
301   // Get the first [n] parts of pattern that are all strings.
302   var n = 0
303   while (typeof pattern[n] === "string") {
304     n ++
305   }
306   // now n is the index of the first one that is *not* a string.
307
308   // see if there's anything else
309   var prefix
310   switch (n) {
311     // if not, then this is rather simple
312     case pattern.length:
313       prefix = pattern.join("/")
314       this._stat(prefix, function (exists, isDir) {
315         // either it's there, or it isn't.
316         // nothing more to do, either way.
317         if (exists) {
318           if (prefix.charAt(0) === "/" && !this.nomount) {
319             prefix = path.join(this.root, prefix)
320           }
321           this.matches[index] = this.matches[index] || {}
322           this.matches[index][prefix] = true
323           this.emitMatch(prefix)
324         }
325         return cb()
326       })
327       return
328
329     case 0:
330       // pattern *starts* with some non-trivial item.
331       // going to readdir(cwd), but not include the prefix in matches.
332       prefix = null
333       break
334
335     default:
336       // pattern has some string bits in the front.
337       // whatever it starts with, whether that's "absolute" like /foo/bar,
338       // or "relative" like "../baz"
339       prefix = pattern.slice(0, n)
340       prefix = prefix.join("/")
341       break
342   }
343
344   // get the list of entries.
345   var read
346   if (prefix === null) read = "."
347   else if (isAbsolute(prefix)) {
348     read = prefix = path.resolve("/", prefix)
349     if (this.debug) console.error('absolute: ', prefix, this.root, pattern)
350   } else read = prefix
351
352   if (this.debug) console.error('readdir(%j)', read, this.cwd, this.root)
353   return this._readdir(read, function (er, entries) {
354     if (er) {
355       // not a directory!
356       // this means that, whatever else comes after this, it can never match
357       return cb()
358     }
359
360     // globstar is special
361     if (pattern[n] === minimatch.GLOBSTAR) {
362       // test without the globstar, and with every child both below
363       // and replacing the globstar.
364       var s = [ pattern.slice(0, n).concat(pattern.slice(n + 1)) ]
365       entries.forEach(function (e) {
366         if (e.charAt(0) === "." && !this.dot) return
367         // instead of the globstar
368         s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1)))
369         // below the globstar
370         s.push(pattern.slice(0, n).concat(e).concat(pattern.slice(n)))
371       }, this)
372
373       // now asyncForEach over this
374       var l = s.length
375       , errState = null
376       s.forEach(function (gsPattern) {
377         this._process(gsPattern, depth + 1, index, function (er) {
378           if (errState) return
379           if (er) return cb(errState = er)
380           if (--l <= 0) return cb()
381         })
382       }, this)
383
384       return
385     }
386
387     // not a globstar
388     // It will only match dot entries if it starts with a dot, or if
389     // dot is set.  Stuff like @(.foo|.bar) isn't allowed.
390     var pn = pattern[n]
391     if (typeof pn === "string") {
392       var found = entries.indexOf(pn) !== -1
393       entries = found ? entries[pn] : []
394     } else {
395       var rawGlob = pattern[n]._glob
396       , dotOk = this.dot || rawGlob.charAt(0) === "."
397
398       entries = entries.filter(function (e) {
399         return (e.charAt(0) !== "." || dotOk) &&
400                (typeof pattern[n] === "string" && e === pattern[n] ||
401                 e.match(pattern[n]))
402       })
403     }
404
405     // If n === pattern.length - 1, then there's no need for the extra stat
406     // *unless* the user has specified "mark" or "stat" explicitly.
407     // We know that they exist, since the readdir returned them.
408     if (n === pattern.length - 1 &&
409         !this.mark &&
410         !this.stat) {
411       entries.forEach(function (e) {
412         if (prefix) {
413           if (prefix !== "/") e = prefix + "/" + e
414           else e = prefix + e
415         }
416         if (e.charAt(0) === "/" && !this.nomount) {
417           e = path.join(this.root, e)
418         }
419
420         this.matches[index] = this.matches[index] || {}
421         this.matches[index][e] = true
422         this.emitMatch(e)
423       }, this)
424       return cb.call(this)
425     }
426
427
428     // now test all the remaining entries as stand-ins for that part
429     // of the pattern.
430     var l = entries.length
431     , errState = null
432     if (l === 0) return cb() // no matches possible
433     entries.forEach(function (e) {
434       var p = pattern.slice(0, n).concat(e).concat(pattern.slice(n + 1))
435       this._process(p, depth + 1, index, function (er) {
436         if (errState) return
437         if (er) return cb(errState = er)
438         if (--l === 0) return cb.call(this)
439       })
440     }, this)
441   })
442
443 }
444
445 Glob.prototype._stat = function (f, cb) {
446   assert(this instanceof Glob)
447   var abs = f
448   if (f.charAt(0) === "/") {
449     abs = path.join(this.root, f)
450   } else if (this.changedCwd) {
451     abs = path.resolve(this.cwd, f)
452   }
453   if (this.debug) console.error('stat', [this.cwd, f, '=', abs])
454   if (f.length > this.maxLength) {
455     var er = new Error("Path name too long")
456     er.code = "ENAMETOOLONG"
457     er.path = f
458     return this._afterStat(f, abs, cb, er)
459   }
460
461   if (this.statCache.hasOwnProperty(f)) {
462     var exists = this.statCache[f]
463     , isDir = exists && (Array.isArray(exists) || exists === 2)
464     if (this.sync) return cb.call(this, !!exists, isDir)
465     return process.nextTick(cb.bind(this, !!exists, isDir))
466   }
467
468   if (this.sync) {
469     var er, stat
470     try {
471       stat = fs.statSync(abs)
472     } catch (e) {
473       er = e
474     }
475     this._afterStat(f, abs, cb, er, stat)
476   } else {
477     fs.stat(abs, this._afterStat.bind(this, f, abs, cb))
478   }
479 }
480
481 Glob.prototype._afterStat = function (f, abs, cb, er, stat) {
482   var exists
483   assert(this instanceof Glob)
484   if (er || !stat) {
485     exists = false
486   } else {
487     exists = stat.isDirectory() ? 2 : 1
488   }
489   this.statCache[f] = this.statCache[f] || exists
490   cb.call(this, !!exists, exists === 2)
491 }
492
493 Glob.prototype._readdir = function (f, cb) {
494   assert(this instanceof Glob)
495   var abs = f
496   if (f.charAt(0) === "/") {
497     abs = path.join(this.root, f)
498   } else if (isAbsolute(f)) {
499     abs = f
500   } else if (this.changedCwd) {
501     abs = path.resolve(this.cwd, f)
502   }
503
504   if (this.debug) console.error('readdir', [this.cwd, f, abs])
505   if (f.length > this.maxLength) {
506     var er = new Error("Path name too long")
507     er.code = "ENAMETOOLONG"
508     er.path = f
509     return this._afterReaddir(f, abs, cb, er)
510   }
511
512   if (this.statCache.hasOwnProperty(f)) {
513     var c = this.statCache[f]
514     if (Array.isArray(c)) {
515       if (this.sync) return cb.call(this, null, c)
516       return process.nextTick(cb.bind(this, null, c))
517     }
518
519     if (!c || c === 1) {
520       // either ENOENT or ENOTDIR
521       var code = c ? "ENOTDIR" : "ENOENT"
522       , er = new Error((c ? "Not a directory" : "Not found") + ": " + f)
523       er.path = f
524       er.code = code
525       if (this.debug) console.error(f, er)
526       if (this.sync) return cb.call(this, er)
527       return process.nextTick(cb.bind(this, er))
528     }
529
530     // at this point, c === 2, meaning it's a dir, but we haven't
531     // had to read it yet, or c === true, meaning it's *something*
532     // but we don't have any idea what.  Need to read it, either way.
533   }
534
535   if (this.sync) {
536     var er, entries
537     try {
538       entries = fs.readdirSync(abs)
539     } catch (e) {
540       er = e
541     }
542     return this._afterReaddir(f, abs, cb, er, entries)
543   }
544
545   fs.readdir(abs, this._afterReaddir.bind(this, f, abs, cb))
546 }
547
548 Glob.prototype._afterReaddir = function (f, abs, cb, er, entries) {
549   assert(this instanceof Glob)
550   if (entries && !er) {
551     this.statCache[f] = entries
552     // if we haven't asked to stat everything for suresies, then just
553     // assume that everything in there exists, so we can avoid
554     // having to stat it a second time.  This also gets us one step
555     // further into ELOOP territory.
556     if (!this.mark && !this.stat) {
557       entries.forEach(function (e) {
558         if (f === "/") e = f + e
559         else e = f + "/" + e
560         this.statCache[e] = true
561       }, this)
562     }
563
564     return cb.call(this, er, entries)
565   }
566
567   // now handle errors, and cache the information
568   if (er) switch (er.code) {
569     case "ENOTDIR": // totally normal. means it *does* exist.
570       this.statCache[f] = 1
571       return cb.call(this, er)
572     case "ENOENT": // not terribly unusual
573     case "ELOOP":
574     case "ENAMETOOLONG":
575     case "UNKNOWN":
576       this.statCache[f] = false
577       return cb.call(this, er)
578     default: // some unusual error.  Treat as failure.
579       this.statCache[f] = false
580       if (this.strict) this.emit("error", er)
581       if (!this.silent) console.error("glob error", er)
582       return cb.call(this, er)
583   }
584 }
585
586 var isAbsolute = process.platform === "win32" ? absWin : absUnix
587
588 function absWin (p) {
589   if (absUnix(p)) return true
590   // pull off the device/UNC bit from a windows path.
591   // from node's lib/path.js
592   var splitDeviceRe =
593         /^([a-zA-Z]:|[\\\/]{2}[^\\\/]+[\\\/][^\\\/]+)?([\\\/])?/
594     , result = splitDeviceRe.exec(p)
595     , device = result[1] || ''
596     , isUnc = device && device.charAt(1) !== ':'
597     , isAbsolute = !!result[2] || isUnc // UNC paths are always absolute
598
599   return isAbsolute
600 }
601
602 function absUnix (p) {
603   return p.charAt(0) === "/" || p === ""
604 }