Exemplo n.º 1
0
        public static bool TryParseFileProperties(
            IEnumerable <string> values,
            string optionName,
            out FilterPredicate <DateTime>?creationTimePredicate,
            out FilterPredicate <DateTime>?modifiedTimePredicate,
            out FilterPredicate <long>?sizePredicate)
        {
            creationTimePredicate = null;
            modifiedTimePredicate = null;
            sizePredicate         = null;

            foreach (string value in values)
            {
                Expression? expression  = null;
                OptionValue?optionValue = null;

                try
                {
                    expression = Expression.Parse(value);

                    if (OptionValues.FileProperty_CreationTime.IsKeyOrShortKey(expression.Identifier))
                    {
                        optionValue = OptionValues.FileProperty_CreationTime;

                        creationTimePredicate = new FilterPredicate <DateTime>(
                            expression,
                            PredicateHelpers.GetDateTimePredicate(expression));
                    }
                    else if (OptionValues.FileProperty_ModifiedTime.IsKeyOrShortKey(expression.Identifier))
                    {
                        optionValue = OptionValues.FileProperty_ModifiedTime;

                        modifiedTimePredicate = new FilterPredicate <DateTime>(
                            expression,
                            PredicateHelpers.GetDateTimePredicate(expression));
                    }
                    else if (OptionValues.FileProperty_Size.IsKeyOrShortKey(expression.Identifier))
                    {
                        optionValue = OptionValues.FileProperty_Size;

                        if (expression.Kind == ExpressionKind.DecrementExpression)
                        {
                            WriteOptionError(value, optionName, HelpProvider.GetExpressionsText("  ", includeDate: false));
                            return(false);
                        }

                        sizePredicate = new FilterPredicate <long>(expression, PredicateHelpers.GetLongPredicate(expression));
                    }
                    else
                    {
                        WriteOptionError(value, optionName, OptionValueProviders.FilePropertiesProvider);
                        return(false);
                    }
                }
                catch (ArgumentException)
                {
                    if (expression != null &&
                        optionValue != null)
                    {
                        WriteOptionValueError(
                            expression.Value,
                            optionValue,
                            HelpProvider.GetExpressionsText(
                                "  ",
                                includeDate: optionValue != OptionValues.FileProperty_Size));
                    }
                    else
                    {
                        WriteOptionError(value, optionName, HelpProvider.GetExpressionsText("  "));
                    }

                    return(false);
                }
            }

            return(true);
        }
Exemplo n.º 2
0
        public static bool TryParse(
            IEnumerable <string> values,
            string optionName,
            OptionValueProvider provider,
            out Filter?filter,
            out FileNamePart namePart,
            bool allowNull = false,
            OptionValueProvider?namePartProvider  = null,
            FileNamePart defaultNamePart          = FileNamePart.Name,
            PatternOptions includedPatternOptions = PatternOptions.None)
        {
            filter   = null;
            namePart = defaultNamePart;

            string?pattern = values.FirstOrDefault();

            if (pattern == null)
            {
                if (allowNull)
                {
                    return(true);
                }
                else
                {
                    throw new InvalidOperationException($"Option '{OptionNames.GetHelpText(optionName)}' is required.");
                }
            }

            TimeSpan            matchTimeout = Regex.InfiniteMatchTimeout;
            string?             groupName    = null;
            string?             separator    = null;
            Func <string, bool>?predicate    = null;

            List <string>?options = null;

            foreach (string option in values.Skip(1))
            {
                int index = option.IndexOfAny(_equalsOrLessThanOrGreaterThanChars);

                if (index != -1)
                {
                    string key = option.Substring(0, index);

                    if (!provider.ContainsKeyOrShortKey(key))
                    {
                        WriteOptionError(option, optionName, provider);
                        return(false);
                    }

                    string value = option.Substring(index + 1);

                    if (OptionValues.Group.IsKeyOrShortKey(key))
                    {
                        groupName = value;
                        continue;
                    }
                    else if (OptionValues.ListSeparator.IsKeyOrShortKey(key))
                    {
                        separator = value;
                        continue;
                    }
                    else if (OptionValues.Part.IsKeyOrShortKey(key))
                    {
                        if (!TryParseAsEnum(
                                value,
                                out namePart,
                                provider: namePartProvider ?? OptionValueProviders.NamePartKindProvider))
                        {
                            WriteOptionValueError(
                                value,
                                OptionValues.Part,
                                namePartProvider ?? OptionValueProviders.NamePartKindProvider);
                            return(false);
                        }

                        continue;
                    }
                    else if (OptionValues.Timeout.IsKeyOrShortKey(key))
                    {
                        if (!TryParseMatchTimeout(value, out matchTimeout))
                        {
                            WriteOptionValueError(value, OptionValues.Timeout);
                            return(false);
                        }

                        continue;
                    }
                }

                if (Expression.TryParse(option, out Expression? expression))
                {
                    if (OptionValues.Length.IsKeyOrShortKey(expression.Identifier) &&
                        provider.ContainsKeyOrShortKey(expression.Identifier))
                    {
                        try
                        {
                            predicate = PredicateHelpers.GetLengthPredicate(expression);
                            continue;
                        }
                        catch (ArgumentException)
                        {
                            WriteOptionValueError(
                                expression.Value,
                                OptionValues.Length,
                                HelpProvider.GetExpressionsText("  ", includeDate: false));
                            return(false);
                        }
                    }
                    else
                    {
                        WriteOptionError(option, optionName, provider);
                        return(false);
                    }
                }

                (options ??= new List <string>()).Add(option);
            }

            if (!TryParseRegexOptions(
                    options,
                    optionName,
                    out RegexOptions regexOptions,
                    out PatternOptions patternOptions,
                    includedPatternOptions,
                    provider))
            {
                return(false);
            }

            switch (patternOptions & (PatternOptions.WholeWord | PatternOptions.WholeLine))
            {
            case PatternOptions.None:
            case PatternOptions.WholeWord:
            case PatternOptions.WholeLine:
            {
                break;
            }

            default:
            {
                string helpValue = OptionValueProviders.PatternOptionsProvider
                                   .GetValue(nameof(PatternOptions.WholeWord)).HelpValue;

                string helpValue2 = OptionValueProviders.PatternOptionsProvider
                                    .GetValue(nameof(PatternOptions.WholeLine)).HelpValue;

                WriteError($"Values '{helpValue}' and '{helpValue2}' cannot be combined.");

                return(false);
            }
            }

            if ((patternOptions & PatternOptions.FromFile) != 0 &&
                !FileSystemHelpers.TryReadAllText(pattern, out pattern, ex => WriteError(ex)))
            {
                return(false);
            }

            pattern = BuildPattern(pattern, patternOptions, separator);

            if (pattern.Length == 0)
            {
                throw new InvalidOperationException(
                          $"Option '{OptionNames.GetHelpText(optionName)}' is invalid: pattern cannot be empty.");
            }

            Regex?regex = null;

            try
            {
                regex = new Regex(pattern, regexOptions, matchTimeout);
            }
            catch (ArgumentException ex)
            {
                WriteError(ex, $"Could not parse regular expression: {ex.Message}");
                return(false);
            }

            int groupIndex = -1;

            if (groupName != null)
            {
                groupIndex = regex.GroupNumberFromName(groupName);
                if (groupIndex == -1)
                {
                    string message = $"Group '{groupName}' does not exist.";

                    string[] groupNames = regex.GetGroupNames();

                    if (groupNames.Length > 1)
                    {
                        message += " Existing group names: "
                                   + $"{TextHelpers.Join(", ", " and ", groupNames.Where(f => f != "0"))}.";
                    }

                    WriteError(message);
                    return(false);
                }
            }

            filter = new Filter(
                regex,
                isNegative: (patternOptions & PatternOptions.Negative) != 0,
                groupNumber: groupIndex,
                predicate: predicate);

            return(true);
        }