diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/StringMatcher.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/StringMatcher.java
index 7ccdd88120a..d24fc15fe39 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/StringMatcher.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/util/StringMatcher.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -26,6 +26,7 @@ public class StringMatcher {
/* boundary value beyond which we don't need to search in the text */
protected int fBound= 0;
+
protected static final char fSingleWildCard= '\u0000';
public static class Position {
@@ -42,104 +43,33 @@ public class StringMatcher {
return end;
}
}
-
/**
- * Find the first occurrence of the pattern between start
end(exclusive).
- * @param text the String object to search in
- * @param start the starting index of the search range, inclusive
- * @param end the ending index of the search range, exclusive
- * @return an StringMatcher.Position
object that keeps the starting
- * (inclusive) and ending positions (exclusive) of the first occurrence of the
- * pattern in the specified range of the text; return null if not found or subtext
- * is empty (start==end). A pair of zeros is returned if pattern is empty string
- * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
- * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
- */
-
- public StringMatcher.Position find(String text, int start, int end) {
- if (fPattern == null || text == null)
- throw new IllegalArgumentException();
-
- int tlen= text.length();
- if (start < 0)
- start= 0;
- if (end > tlen)
- end= tlen;
- if (end < 0 || start >= end)
- return null;
- if (fLength == 0)
- return new Position(start, start);
- if (fIgnoreWildCards) {
- int x= posIn(text, start, end);
- if (x < 0)
- return null;
- return new Position(x, x + fLength);
- }
-
- int segCount= fSegments.length;
- if (segCount == 0) //pattern contains only '*'(s)
- return new Position(start, end);
-
- int curPos= start;
- int matchStart= -1;
- for (int i= 0; i < segCount && curPos < end; ++i) {
- String current= fSegments[i];
- int nextMatch= regExpPosIn(text, curPos, end, current);
- if (nextMatch < 0)
- return null;
- if (i == 0)
- matchStart= nextMatch;
- curPos= nextMatch + current.length();
- }
- return new Position(matchStart, curPos);
- }
- /**
- * StringMatcher constructor takes in a String object that is a simple
- * pattern which may contain * for 0 and many characters and
- * ? for exactly one character. Also takes as parameter a boolean object
- * specifying if case should be ignored
- * @deprecated Use StringMatcher(pattern, ignoreCase, ignoreWildCards).
- */
- @Deprecated
- public StringMatcher(String aPattern, boolean ignoreCase) {
- this(aPattern, ignoreCase, false);
- }
- /**
- * StringMatcher constructor takes in a String object that is a simple
- * pattern which may contain * for 0 and many characters and
- * ? for exactly one character.
+ * StringMatcher constructor takes in a String object that is a simple
+ * pattern. The pattern may contain '*' for 0 and many characters and
+ * '?' for exactly one character.
*
- * Literal '*' and '?' characters must be escaped in the pattern
+ * Literal '*' and '?' characters must be escaped in the pattern
* e.g., "\*" means literal "*", etc.
*
- * Escaping any other character (including the escape character itself),
+ * Escaping any other character (including the escape character itself),
* just results in that character in the pattern.
* e.g., "\a" means "a" and "\\" means "\"
*
* If invoking the StringMatcher with string literals in Java, don't forget
* escape characters are represented by "\\".
*
- * @param aPattern the pattern to match text against
+ * @param pattern the pattern to match text against
* @param ignoreCase if true, case is ignored
* @param ignoreWildCards if true, wild cards and their escape sequences are ignored
* (everything is taken literally).
*/
- public StringMatcher(String aPattern, boolean ignoreCase, boolean ignoreWildCards) {
+ public StringMatcher(String pattern, boolean ignoreCase, boolean ignoreWildCards) {
+ if (pattern == null)
+ throw new IllegalArgumentException();
fIgnoreCase= ignoreCase;
fIgnoreWildCards= ignoreWildCards;
- fLength= aPattern.length();
-
- /* convert case */
- if (fIgnoreCase) {
- char[] chars= aPattern.toCharArray();
- for (int i = 0; i < chars.length; i++) {
- chars[i]= Character.toUpperCase(chars[i]);
- }
- fPattern= new String(chars);
- } else {
- fPattern= aPattern;
- }
+ fPattern= pattern;
+ fLength= pattern.length();
if (fIgnoreWildCards) {
parseNoWildCards();
@@ -148,24 +78,85 @@ public class StringMatcher {
}
}
/**
- * Given the starting (inclusive) and the ending (exclusive) poisitions in the
- * text
, determine if the given substring matches with aPattern
+ * Find the first occurrence of the pattern between start
end(exclusive).
+ * @param text the String object to search in
+ * @param start the starting index of the search range, inclusive
+ * @param end the ending index of the search range, exclusive
+ * @return an StringMatcher.Position
object that keeps the starting
+ * (inclusive) and ending positions (exclusive) of the first occurrence of the
+ * pattern in the specified range of the text; return null if not found or subtext
+ * is empty (start==end). A pair of zeros is returned if pattern is empty string
+ * Note that for pattern like "*abc*" with leading and trailing stars, position of "abc"
+ * is returned. For a pattern like"*??*" in text "abcdf", (1,3) is returned
+ */
+ public StringMatcher.Position find(String text, int start, int end) {
+ if (text == null)
+ throw new IllegalArgumentException();
+
+ int tlen= text.length();
+ if (start < 0)
+ start= 0;
+ if (end > tlen)
+ end= tlen;
+ if (end < 0 ||start >= end )
+ return null;
+ if (fLength == 0)
+ return new Position(start, start);
+ if (fIgnoreWildCards) {
+ int x= posIn(text, start, end);
+ if (x < 0)
+ return null;
+ return new Position(x, x+fLength);
+ }
+
+ int segCount= fSegments.length;
+ if (segCount == 0)//pattern contains only '*'(s)
+ return new Position (start, end);
+
+ int curPos= start;
+ int matchStart= -1;
+ int i;
+ for (i= 0; i < segCount && curPos < end; ++i) {
+ String current= fSegments[i];
+ int nextMatch= regExpPosIn(text, curPos, end, current);
+ if (nextMatch < 0 )
+ return null;
+ if(i == 0)
+ matchStart= nextMatch;
+ curPos= nextMatch + current.length();
+ }
+ if (i < segCount)
+ return null;
+ return new Position(matchStart, curPos);
+ }
+ /**
+ * match the given text
with the pattern
+ * @return true if matched eitherwise false
+ * @param text a String object
+ */
+ public boolean match(String text) {
+ return match(text, 0, text.length());
+ }
+ /**
+ * Given the starting (inclusive) and the ending (exclusive) positions in the
+ * text
, determine if the given substring matches with aPattern
* @return true if the specified portion of the text matches the pattern
- * @param text a String object that contains the substring to match
+ * @param text a String object that contains the substring to match
* @param start marks the starting position (inclusive) of the substring
- * @param end marks the ending index (exclusive) of the substring
+ * @param end marks the ending index (exclusive) of the substring
*/
public boolean match(String text, int start, int end) {
- if (null == fPattern || null == text)
+ if (null == text)
throw new IllegalArgumentException();
if (start > end)
return false;
if (fIgnoreWildCards)
- return fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
+ return (end - start == fLength) && fPattern.regionMatches(fIgnoreCase, 0, text, start, fLength);
int segCount= fSegments.length;
- if (segCount == 0) //pattern contains only '*'(s) or empty pattern
+ if (segCount == 0 && (fHasLeadingStar || fHasTrailingStar)) // pattern contains only '*'(s)
return true;
if (start == end)
return fLength == 0;
@@ -180,23 +171,27 @@ public class StringMatcher {
int tCurPos= start;
int bound= end - fBound;
- if (bound < 0)
+ if ( bound < 0)
return false;
- int i= 0;
+ int i=0;
String current= fSegments[i];
int segLength= current.length();
/* process first segment */
- if (!fHasLeadingStar) {
- if (!regExpRegionMatches(text, start, current, 0, segLength)) {
+ if (!fHasLeadingStar){
+ if(!regExpRegionMatches(text, start, current, 0, segLength)) {
return false;
+ } else {
+ ++i;
+ tCurPos= tCurPos + segLength;
}
- ++i;
- tCurPos= tCurPos + segLength;
}
-
+ if ((fSegments.length == 1) && (!fHasLeadingStar) && (!fHasTrailingStar)) {
+ // only one segment to match, no wildcards specified
+ return tCurPos == end;
+ }
/* process middle segments */
- for (; i < segCount && tCurPos <= bound; ++i) {
+ while (i < segCount) {
current= fSegments[i];
int currentMatch;
int k= current.indexOf(fSingleWildCard);
@@ -210,6 +205,7 @@ public class StringMatcher {
return false;
}
tCurPos= currentMatch + current.length();
+ i++;
}
/* process final segment */
@@ -217,16 +213,9 @@ public class StringMatcher {
int clen= current.length();
return regExpRegionMatches(text, end - clen, current, 0, clen);
}
- return i == segCount;
- }
- /**
- * match the given text
with the pattern
- * @return true if matched eitherwise false
- * @param text a String object
- */
- public boolean match(String text) {
- return match(text, 0, text.length());
+ return i == segCount ;
}
+
/**
* This method parses the given pattern into segments seperated by wildcard '*' characters.
* Since wildcards are not being used in this case, the pattern consists of a single segment.
@@ -237,12 +226,12 @@ public class StringMatcher {
fBound= fLength;
}
/**
- * This method parses the given pattern into segments seperated by wildcard '*' characters.
+ * Parses the given pattern into segments seperated by wildcard '*' characters.
*/
private void parseWildCards() {
- if (fPattern.startsWith("*")) //$NON-NLS-1$
+ if(fPattern.startsWith("*"))//$NON-NLS-1$
fHasLeadingStar= true;
- if (fPattern.endsWith("*")) { //$NON-NLS-1$
+ if(fPattern.endsWith("*")) {//$NON-NLS-1$
/* make sure it's not an escaped wildcard */
if (fLength > 1 && fPattern.charAt(fLength - 2) != '\\') {
fHasTrailingStar= true;
@@ -256,7 +245,7 @@ public class StringMatcher {
while (pos < fLength) {
char c= fPattern.charAt(pos++);
switch (c) {
- case '\\' :
+ case '\\':
if (pos >= fLength) {
buf.append(c);
} else {
@@ -270,20 +259,20 @@ public class StringMatcher {
buf.append(next);
}
}
- break;
- case '*' :
+ break;
+ case '*':
if (buf.length() > 0) {
/* new segment */
temp.addElement(buf.toString());
fBound += buf.length();
buf.setLength(0);
}
- break;
- case '?' :
+ break;
+ case '?':
/* append special character representing single match wildcard */
buf.append(fSingleWildCard);
- break;
- default :
+ break;
+ default:
buf.append(c);
}
}
@@ -297,13 +286,13 @@ public class StringMatcher {
fSegments= new String[temp.size()];
temp.copyInto(fSegments);
}
- /**
+ /**
* @param text a string which contains no wildcard
* @param start the starting index in the text for search, inclusive
* @param end the stopping point of search, exclusive
- * @return the starting index in the text of the pattern , or -1 if not found
+ * @return the starting index in the text of the pattern , or -1 if not found
*/
- protected int posIn(String text, int start, int end) { //no wild card in pattern
+ protected int posIn(String text, int start, int end) {//no wild card in pattern
int max= end - fLength;
if (!fIgnoreCase) {
@@ -320,12 +309,12 @@ public class StringMatcher {
return -1;
}
- /**
+ /**
* @param text a simple regular expression that may only contain '?'(s)
* @param start the starting index in the text for search, inclusive
* @param end the stopping point of search, exclusive
* @param p a simple regular expression that may contains '?'
- * @return the starting index in the text of the pattern , or -1 if not found
+ * @return the starting index in the text of the pattern , or -1 if not found
*/
protected int regExpPosIn(String text, int start, int end, String p) {
int plen= p.length();
@@ -338,6 +327,7 @@ public class StringMatcher {
return -1;
}
+
protected boolean regExpRegionMatches(String text, int tStart, String p, int pStart, int plen) {
while (plen-- > 0) {
char tchar= text.charAt(tStart++);
@@ -353,20 +343,23 @@ public class StringMatcher {
if (pchar == tchar)
continue;
if (fIgnoreCase) {
- char tc= Character.toUpperCase(tchar);
- if (tc == pchar)
+ if (Character.toUpperCase(tchar) == Character.toUpperCase(pchar))
+ continue;
+ // comparing after converting to upper case doesn't handle all cases;
+ // also compare after converting to lower case
+ if (Character.toLowerCase(tchar) == Character.toLowerCase(pchar))
continue;
}
return false;
}
return true;
}
- /**
+ /**
* @param text the string to match
* @param start the starting index in the text for search, inclusive
* @param end the stopping point of search, exclusive
* @param p a string that has no wildcard
- * @return the starting index in the text of the pattern , or -1 if not found
+ * @return the starting index in the text of the pattern , or -1 if not found
*/
protected int textPosIn(String text, int start, int end, String p) {
@@ -380,7 +373,7 @@ public class StringMatcher {
return i;
}
- for (int i= 0; i <= max; ++i) {
+ for (int i= start; i <= max; ++i) {
if (text.regionMatches(true, i, p, 0, plen))
return i;
}