Spaces:
Configuration error
Configuration error
| module.exports = function (glob, opts) { | |
| if (typeof glob !== 'string') { | |
| throw new TypeError('Expected a string'); | |
| } | |
| var str = String(glob); | |
| // The regexp we are building, as a string. | |
| var reStr = ""; | |
| // Whether we are matching so called "extended" globs (like bash) and should | |
| // support single character matching, matching ranges of characters, group | |
| // matching, etc. | |
| var extended = opts ? !!opts.extended : false; | |
| // When globstar is _false_ (default), '/foo/*' is translated a regexp like | |
| // '^\/foo\/.*$' which will match any string beginning with '/foo/' | |
| // When globstar is _true_, '/foo/*' is translated to regexp like | |
| // '^\/foo\/[^/]*$' which will match any string beginning with '/foo/' BUT | |
| // which does not have a '/' to the right of it. | |
| // E.g. with '/foo/*' these will match: '/foo/bar', '/foo/bar.txt' but | |
| // these will not '/foo/bar/baz', '/foo/bar/baz.txt' | |
| // Lastely, when globstar is _true_, '/foo/**' is equivelant to '/foo/*' when | |
| // globstar is _false_ | |
| var globstar = opts ? !!opts.globstar : false; | |
| // If we are doing extended matching, this boolean is true when we are inside | |
| // a group (eg {*.html,*.js}), and false otherwise. | |
| var inGroup = false; | |
| // RegExp flags (eg "i" ) to pass in to RegExp constructor. | |
| var flags = opts && typeof( opts.flags ) === "string" ? opts.flags : ""; | |
| var c; | |
| for (var i = 0, len = str.length; i < len; i++) { | |
| c = str[i]; | |
| switch (c) { | |
| case "/": | |
| case "$": | |
| case "^": | |
| case "+": | |
| case ".": | |
| case "(": | |
| case ")": | |
| case "=": | |
| case "!": | |
| case "|": | |
| reStr += "\\" + c; | |
| break; | |
| case "?": | |
| if (extended) { | |
| reStr += "."; | |
| break; | |
| } | |
| case "[": | |
| case "]": | |
| if (extended) { | |
| reStr += c; | |
| break; | |
| } | |
| case "{": | |
| if (extended) { | |
| inGroup = true; | |
| reStr += "("; | |
| break; | |
| } | |
| case "}": | |
| if (extended) { | |
| inGroup = false; | |
| reStr += ")"; | |
| break; | |
| } | |
| case ",": | |
| if (inGroup) { | |
| reStr += "|"; | |
| break; | |
| } | |
| reStr += "\\" + c; | |
| break; | |
| case "*": | |
| // Move over all consecutive "*"'s. | |
| // Also store the previous and next characters | |
| var prevChar = str[i - 1]; | |
| var starCount = 1; | |
| while(str[i + 1] === "*") { | |
| starCount++; | |
| i++; | |
| } | |
| var nextChar = str[i + 1]; | |
| if (!globstar) { | |
| // globstar is disabled, so treat any number of "*" as one | |
| reStr += ".*"; | |
| } else { | |
| // globstar is enabled, so determine if this is a globstar segment | |
| var isGlobstar = starCount > 1 // multiple "*"'s | |
| && (prevChar === "/" || prevChar === undefined) // from the start of the segment | |
| && (nextChar === "/" || nextChar === undefined) // to the end of the segment | |
| if (isGlobstar) { | |
| // it's a globstar, so match zero or more path segments | |
| reStr += "((?:[^/]*(?:\/|$))*)"; | |
| i++; // move over the "/" | |
| } else { | |
| // it's not a globstar, so only match one path segment | |
| reStr += "([^/]*)"; | |
| } | |
| } | |
| break; | |
| default: | |
| reStr += c; | |
| } | |
| } | |
| // When regexp 'g' flag is specified don't | |
| // constrain the regular expression with ^ & $ | |
| if (!flags || !~flags.indexOf('g')) { | |
| reStr = "^" + reStr + "$"; | |
| } | |
| return new RegExp(reStr, flags); | |
| }; | |