corrade-nucleus-nucleons – Blame information for rev 20

Subversion Repositories:
Rev:
Rev Author Line No. Line
20 office 1 // Based on minimatch.js by isaacs <https://npmjs.org/package/minimatch>
2  
3 ;(function (require, exports, module, platform) {
4  
5 if (module) module.exports = minimatch
6 else exports.minimatch = minimatch
7  
8 if (!require) {
9 require = function (id) {
10 switch (id) {
11 case "sigmund": return function sigmund (obj) {
12 return JSON.stringify(obj)
13 }
14 case "path": return { basename: function (f) {
15 f = f.split(/[\/\\]/)
16 var e = f.pop()
17 if (!e) e = f.pop()
18 return e
19 }}
20 case "lru-cache": return function LRUCache () {
21 // not quite an LRU, but still space-limited.
22 var cache = {}
23 var cnt = 0
24 this.set = function (k, v) {
25 cnt ++
26 if (cnt >= 100) cache = {}
27 cache[k] = v
28 }
29 this.get = function (k) { return cache[k] }
30 }
31 }
32 }
33 }
34  
35 minimatch.Minimatch = Minimatch
36  
37 var LRU = require("lru-cache")
38 , cache = minimatch.cache = new LRU({max: 100})
39 , GLOBSTAR = minimatch.GLOBSTAR = Minimatch.GLOBSTAR = {}
40 , sigmund = require("sigmund")
41  
42 var path = require("path")
43 // any single thing other than /
44 // don't need to escape / when using new RegExp()
45 , qmark = "[^/]"
46  
47 // * => any number of characters
48 , star = qmark + "*?"
49  
50 // ** when dots are allowed. Anything goes, except .. and .
51 // not (^ or / followed by one or two dots followed by $ or /),
52 // followed by anything, any number of times.
53 , twoStarDot = "(?:(?!(?:\\\/|^)(?:\\.{1,2})($|\\\/)).)*?"
54  
55 // not a ^ or / followed by a dot,
56 // followed by anything, any number of times.
57 , twoStarNoDot = "(?:(?!(?:\\\/|^)\\.).)*?"
58  
59 // characters that need to be escaped in RegExp.
60 , reSpecials = charSet("().*{}+?[]^$\\!")
61  
62 // "abc" -> { a:true, b:true, c:true }
63 function charSet (s) {
64 return s.split("").reduce(function (set, c) {
65 set[c] = true
66 return set
67 }, {})
68 }
69  
70 // normalizes slashes.
71 var slashSplit = /\/+/
72  
73 minimatch.monkeyPatch = monkeyPatch
74 function monkeyPatch () {
75 var desc = Object.getOwnPropertyDescriptor(String.prototype, "match")
76 var orig = desc.value
77 desc.value = function (p) {
78 if (p instanceof Minimatch) return p.match(this)
79 return orig.call(this, p)
80 }
81 Object.defineProperty(String.prototype, desc)
82 }
83  
84 minimatch.filter = filter
85 function filter (pattern, options) {
86 options = options || {}
87 return function (p, i, list) {
88 return minimatch(p, pattern, options)
89 }
90 }
91  
92 function ext (a, b) {
93 a = a || {}
94 b = b || {}
95 var t = {}
96 Object.keys(b).forEach(function (k) {
97 t[k] = b[k]
98 })
99 Object.keys(a).forEach(function (k) {
100 t[k] = a[k]
101 })
102 return t
103 }
104  
105 minimatch.defaults = function (def) {
106 if (!def || !Object.keys(def).length) return minimatch
107  
108 var orig = minimatch
109  
110 var m = function minimatch (p, pattern, options) {
111 return orig.minimatch(p, pattern, ext(def, options))
112 }
113  
114 m.Minimatch = function Minimatch (pattern, options) {
115 return new orig.Minimatch(pattern, ext(def, options))
116 }
117  
118 return m
119 }
120  
121 Minimatch.defaults = function (def) {
122 if (!def || !Object.keys(def).length) return Minimatch
123 return minimatch.defaults(def).Minimatch
124 }
125  
126  
127 function minimatch (p, pattern, options) {
128 if (typeof pattern !== "string") {
129 throw new TypeError("glob pattern string required")
130 }
131  
132 if (!options) options = {}
133  
134 // shortcut: comments match nothing.
135 if (!options.nocomment && pattern.charAt(0) === "#") {
136 return false
137 }
138  
139 // "" only matches ""
140 if (pattern.trim() === "") return p === ""
141  
142 return new Minimatch(pattern, options).match(p)
143 }
144  
145 function Minimatch (pattern, options) {
146 if (!(this instanceof Minimatch)) {
147 return new Minimatch(pattern, options, cache)
148 }
149  
150 if (typeof pattern !== "string") {
151 throw new TypeError("glob pattern string required")
152 }
153  
154 if (!options) options = {}
155  
156 // windows: need to use /, not \
157 // On other platforms, \ is a valid (albeit bad) filename char.
158 if (platform === "win32") {
159 pattern = pattern.split("\\").join("/")
160 }
161  
162 // lru storage.
163 // these things aren't particularly big, but walking down the string
164 // and turning it into a regexp can get pretty costly.
165 var cacheKey = pattern + "\n" + sigmund(options)
166 var cached = minimatch.cache.get(cacheKey)
167 if (cached) return cached
168 minimatch.cache.set(cacheKey, this)
169  
170 this.options = options
171 this.set = []
172 this.pattern = pattern
173 this.regexp = null
174 this.negate = false
175 this.comment = false
176 this.empty = false
177  
178 // make the set of regexps etc.
179 this.make()
180 }
181  
182 Minimatch.prototype.make = make
183 function make () {
184 // don't do it more than once.
185 if (this._made) return
186  
187 var pattern = this.pattern
188 var options = this.options
189  
190 // empty patterns and comments match nothing.
191 if (!options.nocomment && pattern.charAt(0) === "#") {
192 this.comment = true
193 return
194 }
195 if (!pattern) {
196 this.empty = true
197 return
198 }
199  
200 // step 1: figure out negation, etc.
201 this.parseNegate()
202  
203 // step 2: expand braces
204 var set = this.globSet = this.braceExpand()
205  
206 if (options.debug) console.error(this.pattern, set)
207  
208 // step 3: now we have a set, so turn each one into a series of path-portion
209 // matching patterns.
210 // These will be regexps, except in the case of "**", which is
211 // set to the GLOBSTAR object for globstar behavior,
212 // and will not contain any / characters
213 set = this.globParts = set.map(function (s) {
214 return s.split(slashSplit)
215 })
216  
217 if (options.debug) console.error(this.pattern, set)
218  
219 // glob --> regexps
220 set = set.map(function (s, si, set) {
221 return s.map(this.parse, this)
222 }, this)
223  
224 if (options.debug) console.error(this.pattern, set)
225  
226 // filter out everything that didn't compile properly.
227 set = set.filter(function (s) {
228 return -1 === s.indexOf(false)
229 })
230  
231 if (options.debug) console.error(this.pattern, set)
232  
233 this.set = set
234 }
235  
236 Minimatch.prototype.parseNegate = parseNegate
237 function parseNegate () {
238 var pattern = this.pattern
239 , negate = false
240 , options = this.options
241 , negateOffset = 0
242  
243 if (options.nonegate) return
244  
245 for ( var i = 0, l = pattern.length
246 ; i < l && pattern.charAt(i) === "!"
247 ; i ++) {
248 negate = !negate
249 negateOffset ++
250 }
251  
252 if (negateOffset) this.pattern = pattern.substr(negateOffset)
253 this.negate = negate
254 }
255  
256 // Brace expansion:
257 // a{b,c}d -> abd acd
258 // a{b,}c -> abc ac
259 // a{0..3}d -> a0d a1d a2d a3d
260 // a{b,c{d,e}f}g -> abg acdfg acefg
261 // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
262 //
263 // Invalid sets are not expanded.
264 // a{2..}b -> a{2..}b
265 // a{b}c -> a{b}c
266 minimatch.braceExpand = function (pattern, options) {
267 return new Minimatch(pattern, options).braceExpand()
268 }
269  
270 Minimatch.prototype.braceExpand = braceExpand
271 function braceExpand (pattern, options) {
272 options = options || this.options
273 pattern = typeof pattern === "undefined"
274 ? this.pattern : pattern
275  
276 if (typeof pattern === "undefined") {
277 throw new Error("undefined pattern")
278 }
279  
280 if (options.nobrace ||
281 !pattern.match(/\{.*\}/)) {
282 // shortcut. no need to expand.
283 return [pattern]
284 }
285  
286 var escaping = false
287  
288 // examples and comments refer to this crazy pattern:
289 // a{b,c{d,e},{f,g}h}x{y,z}
290 // expected:
291 // abxy
292 // abxz
293 // acdxy
294 // acdxz
295 // acexy
296 // acexz
297 // afhxy
298 // afhxz
299 // aghxy
300 // aghxz
301  
302 // everything before the first \{ is just a prefix.
303 // So, we pluck that off, and work with the rest,
304 // and then prepend it to everything we find.
305 if (pattern.charAt(0) !== "{") {
306 // console.error(pattern)
307 var prefix = null
308 for (var i = 0, l = pattern.length; i < l; i ++) {
309 var c = pattern.charAt(i)
310 // console.error(i, c)
311 if (c === "\\") {
312 escaping = !escaping
313 } else if (c === "{" && !escaping) {
314 prefix = pattern.substr(0, i)
315 break
316 }
317 }
318  
319 // actually no sets, all { were escaped.
320 if (prefix === null) {
321 // console.error("no sets")
322 return [pattern]
323 }
324  
325 var tail = braceExpand(pattern.substr(i), options)
326 return tail.map(function (t) {
327 return prefix + t
328 })
329 }
330  
331 // now we have something like:
332 // {b,c{d,e},{f,g}h}x{y,z}
333 // walk through the set, expanding each part, until
334 // the set ends. then, we'll expand the suffix.
335 // If the set only has a single member, then'll put the {} back
336  
337 // first, handle numeric sets, since they're easier
338 var numset = pattern.match(/^\{(-?[0-9]+)\.\.(-?[0-9]+)\}/)
339 if (numset) {
340 // console.error("numset", numset[1], numset[2])
341 var suf = braceExpand(pattern.substr(numset[0].length), options)
342 , start = +numset[1]
343 , end = +numset[2]
344 , inc = start > end ? -1 : 1
345 , set = []
346 for (var i = start; i != (end + inc); i += inc) {
347 // append all the suffixes
348 for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
349 set.push(i + suf[ii])
350 }
351 }
352 return set
353 }
354  
355 // ok, walk through the set
356 // We hope, somewhat optimistically, that there
357 // will be a } at the end.
358 // If the closing brace isn't found, then the pattern is
359 // interpreted as braceExpand("\\" + pattern) so that
360 // the leading \{ will be interpreted literally.
361 var i = 1 // skip the \{
362 , depth = 1
363 , set = []
364 , member = ""
365 , sawEnd = false
366 , escaping = false
367  
368 function addMember () {
369 set.push(member)
370 member = ""
371 }
372  
373 // console.error("Entering for")
374 FOR: for (i = 1, l = pattern.length; i < l; i ++) {
375 var c = pattern.charAt(i)
376 // console.error("", i, c)
377  
378 if (escaping) {
379 escaping = false
380 member += "\\" + c
381 } else {
382 switch (c) {
383 case "\\":
384 escaping = true
385 continue
386  
387 case "{":
388 depth ++
389 member += "{"
390 continue
391  
392 case "}":
393 depth --
394 // if this closes the actual set, then we're done
395 if (depth === 0) {
396 addMember()
397 // pluck off the close-brace
398 i ++
399 break FOR
400 } else {
401 member += c
402 continue
403 }
404  
405 case ",":
406 if (depth === 1) {
407 addMember()
408 } else {
409 member += c
410 }
411 continue
412  
413 default:
414 member += c
415 continue
416 } // switch
417 } // else
418 } // for
419  
420 // now we've either finished the set, and the suffix is
421 // pattern.substr(i), or we have *not* closed the set,
422 // and need to escape the leading brace
423 if (depth !== 0) {
424 // console.error("didn't close", pattern)
425 return braceExpand("\\" + pattern, options)
426 }
427  
428 // x{y,z} -> ["xy", "xz"]
429 // console.error("set", set)
430 // console.error("suffix", pattern.substr(i))
431 var suf = braceExpand(pattern.substr(i), options)
432 // ["b", "c{d,e}","{f,g}h"] ->
433 // [["b"], ["cd", "ce"], ["fh", "gh"]]
434 var addBraces = set.length === 1
435 // console.error("set pre-expanded", set)
436 set = set.map(function (p) {
437 return braceExpand(p, options)
438 })
439 // console.error("set expanded", set)
440  
441  
442 // [["b"], ["cd", "ce"], ["fh", "gh"]] ->
443 // ["b", "cd", "ce", "fh", "gh"]
444 set = set.reduce(function (l, r) {
445 return l.concat(r)
446 })
447  
448 if (addBraces) {
449 set = set.map(function (s) {
450 return "{" + s + "}"
451 })
452 }
453  
454 // now attach the suffixes.
455 var ret = []
456 for (var i = 0, l = set.length; i < l; i ++) {
457 for (var ii = 0, ll = suf.length; ii < ll; ii ++) {
458 ret.push(set[i] + suf[ii])
459 }
460 }
461 return ret
462 }
463  
464 // parse a component of the expanded set.
465 // At this point, no pattern may contain "/" in it
466 // so we're going to return a 2d array, where each entry is the full
467 // pattern, split on '/', and then turned into a regular expression.
468 // A regexp is made at the end which joins each array with an
469 // escaped /, and another full one which joins each regexp with |.
470 //
471 // Following the lead of Bash 4.1, note that "**" only has special meaning
472 // when it is the *only* thing in a path portion. Otherwise, any series
473 // of * is equivalent to a single *. Globstar behavior is enabled by
474 // default, and can be disabled by setting options.noglobstar.
475 Minimatch.prototype.parse = parse
476 var SUBPARSE = {}
477 function parse (pattern, isSub) {
478 var options = this.options
479  
480 // shortcuts
481 if (!options.noglobstar && pattern === "**") return GLOBSTAR
482 if (pattern === "") return ""
483  
484 var re = ""
485 , hasMagic = !!options.nocase
486 , escaping = false
487 // ? => one single character
488 , patternListStack = []
489 , plType
490 , stateChar
491 , inClass = false
492 , reClassStart = -1
493 , classStart = -1
494 // . and .. never match anything that doesn't start with .,
495 // even when options.dot is set.
496 , patternStart = pattern.charAt(0) === "." ? "" // anything
497 // not (start or / followed by . or .. followed by / or end)
498 : options.dot ? "(?!(?:^|\\\/)\\.{1,2}(?:$|\\\/))"
499 : "(?!\\.)"
500  
501 function clearStateChar () {
502 if (stateChar) {
503 // we had some state-tracking character
504 // that wasn't consumed by this pass.
505 switch (stateChar) {
506 case "*":
507 re += star
508 hasMagic = true
509 break
510 case "?":
511 re += qmark
512 hasMagic = true
513 break
514 default:
515 re += "\\"+stateChar
516 break
517 }
518 stateChar = false
519 }
520 }
521  
522 for ( var i = 0, len = pattern.length, c
523 ; (i < len) && (c = pattern.charAt(i))
524 ; i ++ ) {
525  
526 if (options.debug) {
527 console.error("%s\t%s %s %j", pattern, i, re, c)
528 }
529  
530 // skip over any that are escaped.
531 if (escaping && reSpecials[c]) {
532 re += "\\" + c
533 escaping = false
534 continue
535 }
536  
537 SWITCH: switch (c) {
538 case "/":
539 // completely not allowed, even escaped.
540 // Should already be path-split by now.
541 return false
542  
543 case "\\":
544 clearStateChar()
545 escaping = true
546 continue
547  
548 // the various stateChar values
549 // for the "extglob" stuff.
550 case "?":
551 case "*":
552 case "+":
553 case "@":
554 case "!":
555 if (options.debug) {
556 console.error("%s\t%s %s %j <-- stateChar", pattern, i, re, c)
557 }
558  
559 // all of those are literals inside a class, except that
560 // the glob [!a] means [^a] in regexp
561 if (inClass) {
562 if (c === "!" && i === classStart + 1) c = "^"
563 re += c
564 continue
565 }
566  
567 // if we already have a stateChar, then it means
568 // that there was something like ** or +? in there.
569 // Handle the stateChar, then proceed with this one.
570 clearStateChar()
571 stateChar = c
572 // if extglob is disabled, then +(asdf|foo) isn't a thing.
573 // just clear the statechar *now*, rather than even diving into
574 // the patternList stuff.
575 if (options.noext) clearStateChar()
576 continue
577  
578 case "(":
579 if (inClass) {
580 re += "("
581 continue
582 }
583  
584 if (!stateChar) {
585 re += "\\("
586 continue
587 }
588  
589 plType = stateChar
590 patternListStack.push({ type: plType
591 , start: i - 1
592 , reStart: re.length })
593 // negation is (?:(?!js)[^/]*)
594 re += stateChar === "!" ? "(?:(?!" : "(?:"
595 stateChar = false
596 continue
597  
598 case ")":
599 if (inClass || !patternListStack.length) {
600 re += "\\)"
601 continue
602 }
603  
604 hasMagic = true
605 re += ")"
606 plType = patternListStack.pop().type
607 // negation is (?:(?!js)[^/]*)
608 // The others are (?:<pattern>)<type>
609 switch (plType) {
610 case "!":
611 re += "[^/]*?)"
612 break
613 case "?":
614 case "+":
615 case "*": re += plType
616 case "@": break // the default anyway
617 }
618 continue
619  
620 case "|":
621 if (inClass || !patternListStack.length || escaping) {
622 re += "\\|"
623 escaping = false
624 continue
625 }
626  
627 re += "|"
628 continue
629  
630 // these are mostly the same in regexp and glob
631 case "[":
632 // swallow any state-tracking char before the [
633 clearStateChar()
634  
635 if (inClass) {
636 re += "\\" + c
637 continue
638 }
639  
640 inClass = true
641 classStart = i
642 reClassStart = re.length
643 re += c
644 continue
645  
646 case "]":
647 // a right bracket shall lose its special
648 // meaning and represent itself in
649 // a bracket expression if it occurs
650 // first in the list. -- POSIX.2 2.8.3.2
651 if (i === classStart + 1 || !inClass) {
652 re += "\\" + c
653 escaping = false
654 continue
655 }
656  
657 // finish up the class.
658 hasMagic = true
659 inClass = false
660 re += c
661 continue
662  
663 default:
664 // swallow any state char that wasn't consumed
665 clearStateChar()
666  
667 if (escaping) {
668 // no need
669 escaping = false
670 } else if (reSpecials[c]
671 && !(c === "^" && inClass)) {
672 re += "\\"
673 }
674  
675 re += c
676  
677 } // switch
678 } // for
679  
680  
681 // handle the case where we left a class open.
682 // "[abc" is valid, equivalent to "\[abc"
683 if (inClass) {
684 // split where the last [ was, and escape it
685 // this is a huge pita. We now have to re-walk
686 // the contents of the would-be class to re-translate
687 // any characters that were passed through as-is
688 var cs = pattern.substr(classStart + 1)
689 , sp = this.parse(cs, SUBPARSE)
690 re = re.substr(0, reClassStart) + "\\[" + sp[0]
691 hasMagic = hasMagic || sp[1]
692 }
693  
694 // handle the case where we had a +( thing at the *end*
695 // of the pattern.
696 // each pattern list stack adds 3 chars, and we need to go through
697 // and escape any | chars that were passed through as-is for the regexp.
698 // Go through and escape them, taking care not to double-escape any
699 // | chars that were already escaped.
700 var pl
701 while (pl = patternListStack.pop()) {
702 var tail = re.slice(pl.reStart + 3)
703 // maybe some even number of \, then maybe 1 \, followed by a |
704 tail = tail.replace(/((?:\\{2})*)(\\?)\|/g, function (_, $1, $2) {
705 if (!$2) {
706 // the | isn't already escaped, so escape it.
707 $2 = "\\"
708 }
709  
710 // need to escape all those slashes *again*, without escaping the
711 // one that we need for escaping the | character. As it works out,
712 // escaping an even number of slashes can be done by simply repeating
713 // it exactly after itself. That's why this trick works.
714 //
715 // I am sorry that you have to see this.
716 return $1 + $1 + $2 + "|"
717 })
718  
719 // console.error("tail=%j\n %s", tail, tail)
720 var t = pl.type === "*" ? star
721 : pl.type === "?" ? qmark
722 : "\\" + pl.type
723  
724 hasMagic = true
725 re = re.slice(0, pl.reStart)
726 + t + "\\("
727 + tail
728 }
729  
730 // handle trailing things that only matter at the very end.
731 clearStateChar()
732 if (escaping) {
733 // trailing \\
734 re += "\\\\"
735 }
736  
737 // only need to apply the nodot start if the re starts with
738 // something that could conceivably capture a dot
739 var addPatternStart = false
740 switch (re.charAt(0)) {
741 case ".":
742 case "[":
743 case "(": addPatternStart = true
744 }
745  
746 // if the re is not "" at this point, then we need to make sure
747 // it doesn't match against an empty path part.
748 // Otherwise a/* will match a/, which it should not.
749 if (re !== "" && hasMagic) re = "(?=.)" + re
750  
751 if (addPatternStart) re = patternStart + re
752  
753 // parsing just a piece of a larger pattern.
754 if (isSub === SUBPARSE) {
755 return [ re, hasMagic ]
756 }
757  
758 // skip the regexp for non-magical patterns
759 // unescape anything in it, though, so that it'll be
760 // an exact match against a file etc.
761 if (!hasMagic) {
762 return globUnescape(pattern)
763 }
764  
765 var flags = options.nocase ? "i" : ""
766 , regExp = new RegExp("^" + re + "$", flags)
767  
768 regExp._glob = pattern
769 regExp._src = re
770  
771 return regExp
772 }
773  
774 minimatch.makeRe = function (pattern, options) {
775 return new Minimatch(pattern, options || {}).makeRe()
776 }
777  
778 Minimatch.prototype.makeRe = makeRe
779 function makeRe () {
780 if (this.regexp || this.regexp === false) return this.regexp
781  
782 // at this point, this.set is a 2d array of partial
783 // pattern strings, or "**".
784 //
785 // It's better to use .match(). This function shouldn't
786 // be used, really, but it's pretty convenient sometimes,
787 // when you just want to work with a regex.
788 var set = this.set
789  
790 if (!set.length) return this.regexp = false
791 var options = this.options
792  
793 var twoStar = options.noglobstar ? star
794 : options.dot ? twoStarDot
795 : twoStarNoDot
796 , flags = options.nocase ? "i" : ""
797  
798 var re = set.map(function (pattern) {
799 return pattern.map(function (p) {
800 return (p === GLOBSTAR) ? twoStar
801 : (typeof p === "string") ? regExpEscape(p)
802 : p._src
803 }).join("\\\/")
804 }).join("|")
805  
806 // must match entire pattern
807 // ending in a * or ** will make it less strict.
808 re = "^(?:" + re + ")$"
809  
810 // can match anything, as long as it's not this.
811 if (this.negate) re = "^(?!" + re + ").*$"
812  
813 try {
814 return this.regexp = new RegExp(re, flags)
815 } catch (ex) {
816 return this.regexp = false
817 }
818 }
819  
820 minimatch.match = function (list, pattern, options) {
821 var mm = new Minimatch(pattern, options)
822 list = list.filter(function (f) {
823 return mm.match(f)
824 })
825 if (options.nonull && !list.length) {
826 list.push(pattern)
827 }
828 return list
829 }
830  
831 Minimatch.prototype.match = match
832 function match (f, partial) {
833 // console.error("match", f, this.pattern)
834 // short-circuit in the case of busted things.
835 // comments, etc.
836 if (this.comment) return false
837 if (this.empty) return f === ""
838  
839 if (f === "/" && partial) return true
840  
841 var options = this.options
842  
843 // windows: need to use /, not \
844 // On other platforms, \ is a valid (albeit bad) filename char.
845 if (platform === "win32") {
846 f = f.split("\\").join("/")
847 }
848  
849 // treat the test path as a set of pathparts.
850 f = f.split(slashSplit)
851 if (options.debug) {
852 console.error(this.pattern, "split", f)
853 }
854  
855 // just ONE of the pattern sets in this.set needs to match
856 // in order for it to be valid. If negating, then just one
857 // match means that we have failed.
858 // Either way, return on the first hit.
859  
860 var set = this.set
861 // console.error(this.pattern, "set", set)
862  
863 for (var i = 0, l = set.length; i < l; i ++) {
864 var pattern = set[i]
865 var hit = this.matchOne(f, pattern, partial)
866 if (hit) {
867 if (options.flipNegate) return true
868 return !this.negate
869 }
870 }
871  
872 // didn't get any hits. this is success if it's a negative
873 // pattern, failure otherwise.
874 if (options.flipNegate) return false
875 return this.negate
876 }
877  
878 // set partial to true to test if, for example,
879 // "/a/b" matches the start of "/*/b/*/d"
880 // Partial means, if you run out of file before you run
881 // out of pattern, then that's fine, as long as all
882 // the parts match.
883 Minimatch.prototype.matchOne = function (file, pattern, partial) {
884 var options = this.options
885  
886 if (options.debug) {
887 console.error("matchOne",
888 { "this": this
889 , file: file
890 , pattern: pattern })
891 }
892  
893 if (options.matchBase && pattern.length === 1) {
894 file = path.basename(file.join("/")).split("/")
895 }
896  
897 if (options.debug) {
898 console.error("matchOne", file.length, pattern.length)
899 }
900  
901 for ( var fi = 0
902 , pi = 0
903 , fl = file.length
904 , pl = pattern.length
905 ; (fi < fl) && (pi < pl)
906 ; fi ++, pi ++ ) {
907  
908 if (options.debug) {
909 console.error("matchOne loop")
910 }
911 var p = pattern[pi]
912 , f = file[fi]
913  
914 if (options.debug) {
915 console.error(pattern, p, f)
916 }
917  
918 // should be impossible.
919 // some invalid regexp stuff in the set.
920 if (p === false) return false
921  
922 if (p === GLOBSTAR) {
923 if (options.debug)
924 console.error('GLOBSTAR', [pattern, p, f])
925  
926 // "**"
927 // a/**/b/**/c would match the following:
928 // a/b/x/y/z/c
929 // a/x/y/z/b/c
930 // a/b/x/b/x/c
931 // a/b/c
932 // To do this, take the rest of the pattern after
933 // the **, and see if it would match the file remainder.
934 // If so, return success.
935 // If not, the ** "swallows" a segment, and try again.
936 // This is recursively awful.
937 //
938 // a/**/b/**/c matching a/b/x/y/z/c
939 // - a matches a
940 // - doublestar
941 // - matchOne(b/x/y/z/c, b/**/c)
942 // - b matches b
943 // - doublestar
944 // - matchOne(x/y/z/c, c) -> no
945 // - matchOne(y/z/c, c) -> no
946 // - matchOne(z/c, c) -> no
947 // - matchOne(c, c) yes, hit
948 var fr = fi
949 , pr = pi + 1
950 if (pr === pl) {
951 if (options.debug)
952 console.error('** at the end')
953 // a ** at the end will just swallow the rest.
954 // We have found a match.
955 // however, it will not swallow /.x, unless
956 // options.dot is set.
957 // . and .. are *never* matched by **, for explosively
958 // exponential reasons.
959 for ( ; fi < fl; fi ++) {
960 if (file[fi] === "." || file[fi] === ".." ||
961 (!options.dot && file[fi].charAt(0) === ".")) return false
962 }
963 return true
964 }
965  
966 // ok, let's see if we can swallow whatever we can.
967 WHILE: while (fr < fl) {
968 var swallowee = file[fr]
969  
970 if (options.debug) {
971 console.error('\nglobstar while',
972 file, fr, pattern, pr, swallowee)
973 }
974  
975 // XXX remove this slice. Just pass the start index.
976 if (this.matchOne(file.slice(fr), pattern.slice(pr), partial)) {
977 if (options.debug)
978 console.error('globstar found match!', fr, fl, swallowee)
979 // found a match.
980 return true
981 } else {
982 // can't swallow "." or ".." ever.
983 // can only swallow ".foo" when explicitly asked.
984 if (swallowee === "." || swallowee === ".." ||
985 (!options.dot && swallowee.charAt(0) === ".")) {
986 if (options.debug)
987 console.error("dot detected!", file, fr, pattern, pr)
988 break WHILE
989 }
990  
991 // ** swallows a segment, and continue.
992 if (options.debug)
993 console.error('globstar swallow a segment, and continue')
994 fr ++
995 }
996 }
997 // no match was found.
998 // However, in partial mode, we can't say this is necessarily over.
999 // If there's more *pattern* left, then
1000 if (partial) {
1001 // ran out of file
1002 // console.error("\n>>> no match, partial?", file, fr, pattern, pr)
1003 if (fr === fl) return true
1004 }
1005 return false
1006 }
1007  
1008 // something other than **
1009 // non-magic patterns just have to match exactly
1010 // patterns with magic have been turned into regexps.
1011 var hit
1012 if (typeof p === "string") {
1013 if (options.nocase) {
1014 hit = f.toLowerCase() === p.toLowerCase()
1015 } else {
1016 hit = f === p
1017 }
1018 if (options.debug) {
1019 console.error("string match", p, f, hit)
1020 }
1021 } else {
1022 hit = f.match(p)
1023 if (options.debug) {
1024 console.error("pattern match", p, f, hit)
1025 }
1026 }
1027  
1028 if (!hit) return false
1029 }
1030  
1031 // Note: ending in / means that we'll get a final ""
1032 // at the end of the pattern. This can only match a
1033 // corresponding "" at the end of the file.
1034 // If the file ends in /, then it can only match a
1035 // a pattern that ends in /, unless the pattern just
1036 // doesn't have any more for it. But, a/b/ should *not*
1037 // match "a/b/*", even though "" matches against the
1038 // [^/]*? pattern, except in partial mode, where it might
1039 // simply not be reached yet.
1040 // However, a/b/ should still satisfy a/*
1041  
1042 // now either we fell off the end of the pattern, or we're done.
1043 if (fi === fl && pi === pl) {
1044 // ran out of pattern and filename at the same time.
1045 // an exact hit!
1046 return true
1047 } else if (fi === fl) {
1048 // ran out of file, but still had pattern left.
1049 // this is ok if we're doing the match as part of
1050 // a glob fs traversal.
1051 return partial
1052 } else if (pi === pl) {
1053 // ran out of pattern, still have file left.
1054 // this is only acceptable if we're on the very last
1055 // empty segment of a file with a trailing slash.
1056 // a/* should match a/b/
1057 var emptyFileEnd = (fi === fl - 1) && (file[fi] === "")
1058 return emptyFileEnd
1059 }
1060  
1061 // should be unreachable.
1062 throw new Error("wtf?")
1063 }
1064  
1065  
1066 // replace stuff like \* with *
1067 function globUnescape (s) {
1068 return s.replace(/\\(.)/g, "$1")
1069 }
1070  
1071  
1072 function regExpEscape (s) {
1073 return s.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&")
1074 }
1075  
1076 })( typeof require === "function" ? require : null,
1077 this,
1078 typeof module === "object" ? module : null,
1079 typeof process === "object" ? process.platform : "win32"
1080 )