Beispiel #1
0
        ///<summary>Tests a single input against a pattern.</summary>
        ///<remarks>This function reparses this input on each invocation.  For performance, avoid this function and reuse a Minimatcher instance instead.</remarks>
        public static bool Check(string input, string pattern, GlobMatcherOptions options = null)
        {
            if (input == null)
            {
                throw new ArgumentNullException("input");
            }
            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }

            // shortcut: comments match nothing.
            if (options != null && !options.NoComment && pattern[0] == '#')
            {
                return(false);
            }

            // "" only matches ""
            if (String.IsNullOrWhiteSpace(pattern))
            {
                return(input == "");
            }

            return(new GlobMatcher(pattern, options).IsMatch(input));
        }
Beispiel #2
0
        ///<summary>Creates a new Minimatcher instance, parsing the pattern into a regex.</summary>
        public GlobMatcher(string pattern, GlobMatcherOptions options = null)
        {
            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }
            this.options = options ?? new GlobMatcherOptions();
            this.pattern = pattern.Trim();
            if (this.options.AllowWindowsPaths)
            {
                this.pattern = this.pattern.Replace('\\', '/');
            }

            this.Make();
        }
Beispiel #3
0
        ///<summary>Creates a filter function that tests input against a pattern.</summary>
        public static Func <string, bool> CreateFilter(string pattern, GlobMatcherOptions options = null)
        {
            if (pattern == null)
            {
                throw new ArgumentNullException("pattern");
            }
            // "" only matches ""
            if (String.IsNullOrWhiteSpace(pattern))
            {
                return(String.IsNullOrEmpty);
            }

            var m = new GlobMatcher(pattern, options);

            return(m.IsMatch);
        }
Beispiel #4
0
 public override bool Match(string input, GlobMatcherOptions options)
 {
     throw new NotSupportedException();
 }
Beispiel #5
0
 public override string RegexSource(GlobMatcherOptions options)
 {
     return(options.NoGlobStar ? star
     : options.Dot?twoStarDot
            : twoStarNoDot);
 }
Beispiel #6
0
 public override bool Match(string input, GlobMatcherOptions options)
 {
     return(regex.Value.IsMatch(input));
 }
Beispiel #7
0
 public override string RegexSource(GlobMatcherOptions options)
 {
     return(Source);
 }
Beispiel #8
0
 public MagicItem(string source, GlobMatcherOptions options)
 {
     Source = source;
     regex  = new Lazy <Regex>(() => new Regex("^" + source + "$", options.RegexOptions));
 }
Beispiel #9
0
 public override bool Match(string input, GlobMatcherOptions options)
 {
     return(input.Equals(Source, options.NoCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal));
 }
Beispiel #10
0
 public abstract bool Match(string input, GlobMatcherOptions options);
Beispiel #11
0
 public abstract string RegexSource(GlobMatcherOptions options);
Beispiel #12
0
        // Brace expansion:
        // a{b,c}d -> abd acd
        // a{b,}c -> abc ac
        // a{0..3}d -> a0d a1d a2d a3d
        // a{b,c{d,e}f}g -> abg acdfg acefg
        // a{b,c}d{e,f}g -> abdeg acdeg abdeg abdfg
        //
        // Invalid sets are not expanded.
        // a{2..}b -> a{2..}b
        // a{b}c -> a{b}c
        ///<summary>Expands all brace ranges in a pattern, returning a sequence containing every possible combination.</summary>
        public static IEnumerable <string> BraceExpand(string pattern, GlobMatcherOptions options)
        {
            if (options.NoBrace || !hasBraces.IsMatch(pattern))
            {
                // shortcut. no need to expand.
                return(new[] { pattern });
            }
            bool escaping = false;
            int  i;

            // examples and comments refer to this crazy pattern:
            // a{b,c{d,e},{f,g}h}x{y,z}
            // expected:
            // abxy
            // abxz
            // acdxy
            // acdxz
            // acexy
            // acexz
            // afhxy
            // afhxz
            // aghxy
            // aghxz

            // everything before the first \{ is just a prefix.
            // So, we pluck that off, and work with the rest,
            // and then prepend it to everything we find.
            if (pattern[0] != '{')
            {
                // console.error(pattern)
                string prefix = null;
                for (i = 0; i < pattern.Length; i++)
                {
                    var c = pattern[i];
                    // console.error(i, c)
                    if (c == '\\')
                    {
                        escaping = !escaping;
                    }
                    else if (c == '{' && !escaping)
                    {
                        prefix = pattern.Substring(0, i);
                        break;
                    }
                }

                // actually no sets, all { were escaped.
                if (prefix == null)
                {
                    // console.error("no sets")
                    return(new[] { pattern });
                }

                return(BraceExpand(pattern.Substring(i), options).Select(t => prefix + t));
            }

            // now we have something like:
            // {b,c{d,e},{f,g}h}x{y,z}
            // walk through the set, expanding each part, until
            // the set ends.  then, we'll expand the suffix.
            // If the set only has a single member, then'll put the {} back

            // first, handle numeric sets, since they're easier
            var numset = numericSet.Match(pattern);

            if (numset.Success)
            {
                // console.error("numset", numset[1], numset[2])
                var suf    = BraceExpand(pattern.Substring(numset.Length), options).ToList();
                int start  = int.Parse(numset.Groups[1].Value),
                    end    = int.Parse(numset.Groups[2].Value),
                    inc    = start > end ? -1 : 1;
                var retVal = new List <string>();
                for (var w = start; w != (end + inc); w += inc)
                {
                    // append all the suffixes
                    for (var ii = 0; ii < suf.Count; ii++)
                    {
                        retVal.Add(w.ToString() + suf[ii]);
                    }
                }
                return(retVal);
            }

            // ok, walk through the set
            // We hope, somewhat optimistically, that there
            // will be a } at the end.
            // If the closing brace isn't found, then the pattern is
            // interpreted as braceExpand("\\" + pattern) so that
            // the leading \{ will be interpreted literally.
            i = 1; // skip the \{
            int    depth  = 1;
            var    set    = new List <string>();
            string member = "";

            for (i = 1; i < pattern.Length && depth > 0; i++)
            {
                var c = pattern[i];
                // console.error("", i, c)

                if (escaping)
                {
                    escaping = false;
                    member  += "\\" + c;
                }
                else
                {
                    switch (c)
                    {
                    case '\\':
                        escaping = true;
                        continue;

                    case '{':
                        depth++;
                        member += "{";
                        continue;

                    case '}':
                        depth--;
                        // if this closes the actual set, then we're done
                        if (depth == 0)
                        {
                            set.Add(member);
                            member = "";
                            // pluck off the close-brace
                            break;
                        }
                        else
                        {
                            member += c;
                            continue;
                        }

                    case ',':
                        if (depth == 1)
                        {
                            set.Add(member);
                            member = "";
                        }
                        else
                        {
                            member += c;
                        }
                        continue;

                    default:
                        member += c;
                        continue;
                    } // switch
                }     // else
            }         // for

            // now we've either finished the set, and the suffix is
            // pattern.substr(i), or we have *not* closed the set,
            // and need to escape the leading brace
            if (depth != 0)
            {
                // console.error("didn't close", pattern)
                return(BraceExpand("\\" + pattern, options));
            }

            // ["b", "c{d,e}","{f,g}h"] ->
            //   ["b", "cd", "ce", "fh", "gh"]
            var addBraces = set.Count == 1;

            set = set.SelectMany(p => BraceExpand(p, options)).ToList();

            if (addBraces)
            {
                set = set.Select(s => "{" + s + "}").ToList();
            }
            // now attach the suffixes.
            // x{y,z} -> ["xy", "xz"]
            // console.error("set", set)
            // console.error("suffix", pattern.substr(i))
            return(BraceExpand(pattern.Substring(i), options).SelectMany(s1 => set.Select(s2 => s2 + s1)));
        }
Beispiel #13
0
 ///<summary>Compiles a pattern into a single regular expression.</summary>
 public static Regex CreateRegex(string pattern, GlobMatcherOptions options = null)
 {
     return(new GlobMatcher(pattern, options).MakeRegex());
 }
Beispiel #14
0
        ///<summary>Filters a list of inputs against a single pattern.</summary>
        ///<remarks>This function reparses this input on each invocation.  For performance, avoid this function and reuse a Minimatcher instance instead.</remarks>
        public static IEnumerable <string> Filter(IEnumerable <string> list, string pattern, GlobMatcherOptions options = null)
        {
            var mm = new GlobMatcher(pattern, options);

            list = list.Where(mm.IsMatch);
            if (options != null && options.NoNull)
            {
                list = list.DefaultIfEmpty(pattern);
            }
            return(list);
        }