예제 #1
0
        static XPathInput Parse(string[] lines)
        {
            var result = new XPathInput
            {
                Variables = new Dictionary <string, object>()
            };

            var  regex1 = new Regex(@"^declare\s+variable\s+\$(\w+)\s+(.*)");
            var  regex2 = new Regex(@"^external[;\s]*$");
            var  regex3 = new Regex(@"^:=\s*(.*?)[;\s]*$");
            int  i;
            bool comment = false;

            for (i = 0; i < lines.Length; ++i)
            {
                var line = lines[i].Trim();

repeat:

                // empty line
                if (line.Length == 0)
                {
                    continue;
                }

                // comment
                if (comment)
                {
                    int index = line.IndexOf(":)", StringComparison.Ordinal);
                    if (index < 0)
                    {
                        continue;
                    }

                    line    = line.Substring(index + 2).Trim();
                    comment = false;
                    goto repeat;
                }
                else if (line.StartsWith("(:", StringComparison.Ordinal))
                {
                    line    = line.Substring(2);
                    comment = true;
                    goto repeat;
                }

                var match = regex1.Match(line);
                if (!match.Success)
                {
                    break;
                }

                var name = match.Groups[1].Value;
                var text = match.Groups[2].Value;
                match = regex2.Match(text);
                if (match.Success)
                {
                    // prompt
                    text = Far.Api.Input("Variable: " + name, "XPathVariable", "Input variable");
                    if (text == null)
                    {
                        result.Variables.Add(name, string.Empty);
                        continue;
                    }

                    if (double.TryParse(text, out double adouble))
                    {
                        result.Variables.Add(name, adouble);
                    }
                    else
                    {
                        result.Variables.Add(name, text);
                    }
                    continue;
                }

                match = regex3.Match(text);
                if (!match.Success)
                {
                    throw new InvalidOperationException("declare variable: expected 'external' or ':='");
                }

                text = match.Groups[1].Value;
                if (text.StartsWith("'", StringComparison.Ordinal) && text.EndsWith("'", StringComparison.Ordinal) ||
                    text.StartsWith("\"", StringComparison.Ordinal) && text.EndsWith("\"", StringComparison.Ordinal))
                {
                    result.Variables.Add(name, text.Substring(1, text.Length - 2));
                }
                else
                {
                    if (!double.TryParse(text, out double adouble))
                    {
                        throw new InvalidOperationException("Not supported variable value.");
                    }
                    result.Variables.Add(name, adouble);
                }
            }

            result.Expression = string.Join(Environment.NewLine, lines, i, lines.Length - i);
            return(result);
        }
예제 #2
0
        IEnumerable <FarFile> DoInvokeXPath(ProgressBox progress)
        {
            // object context
            var objectContext = new XPathObjectContext()
            {
                Filter = this.Filter,
                IncrementDirectoryCount = delegate(int count)
                {
                    ProcessedDirectoryCount += count;
                    if (progress == null)
                    {
                        return;
                    }

                    var directoryPerSecond = ProcessedDirectoryCount / progress.ElapsedFromStart.TotalSeconds;
                    progress.Activity = string.Format(null, Res.SearchActivityDeep,
                                                      FoundFileCount, ProcessedDirectoryCount, directoryPerSecond);
                    progress.ShowProgress();
                },
                Stopping = delegate
                {
                    return(Stopping || progress != null && UIUserStop());
                }
            };

            var xsltContext = new XPathXsltContext(objectContext.NameTable);

            if (_XVariables != null)
            {
                foreach (var kv in _XVariables)
                {
                    xsltContext.AddVariable(kv.Key, kv.Value);
                }
            }

            // XPath text
            string xpath;

            if (string.IsNullOrEmpty(XFile))
            {
                xpath = XPath;
            }
            else
            {
                var input = XPathInput.ParseFile(XFile);
                xpath = input.Expression;
                foreach (var kv in input.Variables)
                {
                    xsltContext.AddVariable(kv.Key, kv.Value);
                }
            }

            var expression = XPathExpression.Compile(xpath);

            if (expression.ReturnType != XPathResultType.NodeSet)
            {
                throw new InvalidOperationException("Invalid expression return type.");
            }
            expression.SetContext(xsltContext);

            ++ProcessedDirectoryCount;
            var args = new GetFilesEventArgs(ExplorerModes.Find);

            foreach (var file in _RootExplorer.GetFiles(args))
            {
                // stop?
                if (Stopping || progress != null && UIUserStop())                 //???? progress to navigator
                {
                    break;
                }

                // filter out a leaf
                if (Filter != null && !file.IsDirectory && !Filter(_RootExplorer, file))
                {
                    continue;
                }

                var xfile     = new SuperFile(_RootExplorer, file);
                var navigator = new XPathObjectNavigator(xfile, objectContext);
                var iterator  = navigator.Select(expression);
                while (iterator.MoveNext())
                {
                    // stop?
                    if (Stopping || progress != null && UIUserStop())                     //???? progress to navigator
                    {
                        break;
                    }

                    // found file or directory, ignore anything else
                    if (!(iterator.Current.UnderlyingObject is SuperFile currentFile))
                    {
                        continue;
                    }

                    // filter out directory, it is already done for files
                    if (Filter != null && currentFile.IsDirectory && (!Directory || !Filter(currentFile.Explorer, currentFile.File)))
                    {
                        continue;
                    }

                    // add
                    yield return(currentFile);

                    ++FoundFileCount;
                }
            }
        }
예제 #3
0
        static XPathInput Parse(string[] lines)
        {
            var result = new XPathInput();
            result.Variables = new Dictionary<string, object>();

            var regex1 = new Regex(@"^declare\s+variable\s+\$(\w+)\s+(.*)");
            var regex2 = new Regex(@"^external[;\s]*$");
            var regex3 = new Regex(@"^:=\s*(.*?)[;\s]*$");
            int i;
            bool comment = false;
            for (i = 0; i < lines.Length; ++i)
            {
                var line = lines[i].Trim();

            repeat:

                // empty line
                if (line.Length == 0)
                    continue;

                // comment
                if (comment)
                {
                    int index = line.IndexOf(":)", StringComparison.Ordinal);
                    if (index < 0)
                        continue;

                    line = line.Substring(index + 2).Trim();
                    comment = false;
                    goto repeat;
                }
                else if (line.StartsWith("(:", StringComparison.Ordinal))
                {
                    line = line.Substring(2);
                    comment = true;
                    goto repeat;
                }

                var match = regex1.Match(line);
                if (!match.Success)
                    break;

                var name = match.Groups[1].Value;
                var text = match.Groups[2].Value;
                match = regex2.Match(text);
                if (match.Success)
                {
                    // prompt
                    text = Far.Api.Input("Variable: " + name, "XPathVariable", "Input variable");
                    if (text == null)
                    {
                        result.Variables.Add(name, string.Empty);
                        continue;
                    }

                    double adouble;
                    if (double.TryParse(text, out adouble))
                        result.Variables.Add(name, adouble);
                    else
                        result.Variables.Add(name, text);
                    continue;
                }

                match = regex3.Match(text);
                if (!match.Success)
                    throw new InvalidOperationException("declare variable: expected 'external' or ':='");

                text = match.Groups[1].Value;
                if (text.StartsWith("'", StringComparison.Ordinal) && text.EndsWith("'", StringComparison.Ordinal) ||
                    text.StartsWith("\"", StringComparison.Ordinal) && text.EndsWith("\"", StringComparison.Ordinal))
                {
                    result.Variables.Add(name, text.Substring(1, text.Length - 2));
                }
                else
                {
                    double adouble;
                    if (!double.TryParse(text, out adouble))
                        throw new InvalidOperationException("Not supported variable value.");
                    result.Variables.Add(name, adouble);
                }
            }

            result.Expression = string.Join(Environment.NewLine, lines, i, lines.Length - i);
            return result;
        }