2
// <copyright see="prj:///doc/copyright.txt"/>
3
// <license see="prj:///doc/license.txt"/>
4
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
5
// <version value="$version"/>
9
using System.Collections;
11
using MonoDevelop.Core.Properties;
12
using MonoDevelop.Internal.Undo;
14
using MonoDevelop.SourceEditor.Gui;
16
namespace MonoDevelop.TextEditor.Document
19
/// Implements a wildcard search strategy.
21
/// Wildcard search has following pattern code :
22
/// * = Zero or more of any character
23
/// ? = Any single character
24
/// # = Any single digit
25
/// [...] = Any one character in the set
26
/// [!...] = Any one character not in the set
28
public class WildcardSearchStrategy : ISearchStrategy
40
public CommandType CommandType = CommandType.Match;
41
public char SingleChar = '\0';
42
public string CharList = String.Empty;
45
ArrayList patternProgram = null;
46
int curMatchCharCount = 0;
48
void CompilePattern(string pattern, bool ignoreCase)
50
patternProgram = new ArrayList();
51
for (int i = 0; i < pattern.Length; ++i) {
52
Command newCommand = new Command();
55
newCommand.CommandType = CommandType.AnyDigit;
58
newCommand.CommandType = CommandType.AnyZeroOrMore;
61
newCommand.CommandType = CommandType.AnySingle;
64
int index = pattern.IndexOf(']', i);
66
newCommand.CommandType = CommandType.AnyInList;
67
string list = pattern.Substring(i + 1, index - i - 1);
69
newCommand.CommandType = CommandType.NoneInList;
70
list = list.Substring(1);
72
newCommand.CharList = ignoreCase ? list.ToUpper() : list;
79
newCommand.CommandType = CommandType.Match;
80
newCommand.SingleChar = ignoreCase ? Char.ToUpper(pattern[i]) : pattern[i];
83
patternProgram.Add(newCommand);
87
int Match (ITextIterator textIterator, bool ignoreCase, int programStart)
89
int matchCharCount = 0;
90
bool moreChars = true;
91
for (int pc = programStart; pc < patternProgram.Count; ++pc)
93
if (!moreChars) return -1;
95
char ch = ignoreCase ? Char.ToUpper(textIterator.Current) : textIterator.Current;
96
Command cmd = (Command)patternProgram[pc];
98
switch (cmd.CommandType) {
99
case CommandType.Match:
100
if (ch != cmd.SingleChar) {
104
case CommandType.AnyZeroOrMore:
105
int p = textIterator.Position;
106
int subMatch = Match (textIterator, ignoreCase, pc + 1);
107
if (subMatch != -1) return matchCharCount + subMatch;
108
textIterator.Position = p;
109
if (!textIterator.MoveAhead (1)) return -1;
110
subMatch = Match (textIterator, ignoreCase, pc);
111
if (subMatch != -1) return matchCharCount + subMatch;
113
case CommandType.AnySingle:
115
case CommandType.AnyDigit:
116
if (!Char.IsDigit(ch)) {
120
case CommandType.AnyInList:
121
if (cmd.CharList.IndexOf(ch) < 0) {
125
case CommandType.NoneInList:
126
if (cmd.CharList.IndexOf(ch) >= 0) {
132
moreChars = textIterator.MoveAhead (1);
134
return matchCharCount;
137
int InternalFindNext(ITextIterator textIterator, SearchOptions options)
139
while (textIterator.MoveAhead(1))
141
int pos = textIterator.Position;
142
int charCount = Match (textIterator, options.IgnoreCase, 0);
143
textIterator.Position = pos;
144
if (charCount != -1) {
145
if (!options.SearchWholeWordOnly || SearchReplaceUtilities.IsWholeWordAt (textIterator, charCount))
152
public void CompilePattern(SearchOptions options)
154
CompilePattern(options.SearchPattern, options.IgnoreCase);
157
public ISearchResult FindNext(ITextIterator textIterator, SearchOptions options)
159
int charCount = InternalFindNext(textIterator, options);
160
return charCount != -1 ? new DefaultSearchResult (textIterator.Position, charCount) : null;