mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-21 16:05:25 +02:00
Bug 298069: Wrong encoding for lines in search result.
This commit is contained in:
parent
4733439ba4
commit
d27a79d465
2 changed files with 263 additions and 257 deletions
|
@ -61,7 +61,7 @@ Export-Package: org.eclipse.cdt.core,
|
||||||
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.model.ext;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.parser;x-internal:=true,
|
org.eclipse.cdt.internal.core.parser;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.parser.problem;x-internal:=true,
|
org.eclipse.cdt.internal.core.parser.problem;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.parser.scanner;x-internal:=true,
|
org.eclipse.cdt.internal.core.parser.scanner;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.parser.token;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.parser.token;x-friends:="org.eclipse.cdt.ui",
|
||||||
org.eclipse.cdt.internal.core.parser.util;x-internal:=true,
|
org.eclipse.cdt.internal.core.parser.util;x-internal:=true,
|
||||||
org.eclipse.cdt.internal.core.pdom;x-friends:="org.eclipse.cdt.ui",
|
org.eclipse.cdt.internal.core.pdom;x-friends:="org.eclipse.cdt.ui",
|
||||||
|
|
|
@ -1,256 +1,262 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2009 QNX Software Systems and others.
|
* Copyright (c) 2009, 2010 QNX Software Systems and others.
|
||||||
* All rights reserved. This program and the accompanying materials
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Andrey Eremchenko, kamre@ngs.ru - 222495 C/C++ search should show line matches and line numbers
|
* Andrey Eremchenko, kamre@ngs.ru - 222495 C/C++ search should show line matches and line numbers
|
||||||
*******************************************************************************/
|
* Markus Schorn (Wind River Systems)
|
||||||
package org.eclipse.cdt.internal.ui.search;
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.ui.search;
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.jface.text.BadLocationException;
|
import org.eclipse.jface.text.BadLocationException;
|
||||||
import org.eclipse.jface.text.IDocument;
|
import org.eclipse.jface.text.IDocument;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
import org.eclipse.cdt.core.index.IIndexFileLocation;
|
||||||
import org.eclipse.cdt.core.model.ICElement;
|
import org.eclipse.cdt.core.model.ICElement;
|
||||||
import org.eclipse.cdt.core.parser.CodeReader;
|
import org.eclipse.cdt.core.parser.FileContent;
|
||||||
import org.eclipse.cdt.ui.CUIPlugin;
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
|
||||||
/**
|
import org.eclipse.cdt.internal.core.parser.scanner.AbstractCharArray;
|
||||||
* Element representing a line with one ore more matches.
|
import org.eclipse.cdt.internal.core.parser.scanner.InternalFileContent;
|
||||||
*/
|
|
||||||
public class LineSearchElement extends PDOMSearchElement {
|
/**
|
||||||
public static final class Match {
|
* Element representing a line with one ore more matches.
|
||||||
private final int fOffset;
|
*/
|
||||||
private final int fLength;
|
public class LineSearchElement extends PDOMSearchElement {
|
||||||
private final boolean fIsPolymorphicCall;
|
public static final class Match {
|
||||||
private final ICElement fEnclosingElement;
|
private final int fOffset;
|
||||||
|
private final int fLength;
|
||||||
public Match(int offset, int length, boolean isPolymorphicCall, ICElement enclosingElement) {
|
private final boolean fIsPolymorphicCall;
|
||||||
fOffset = offset;
|
private final ICElement fEnclosingElement;
|
||||||
fLength = length;
|
|
||||||
fIsPolymorphicCall = isPolymorphicCall;
|
public Match(int offset, int length, boolean isPolymorphicCall, ICElement enclosingElement) {
|
||||||
fEnclosingElement = enclosingElement;
|
fOffset = offset;
|
||||||
}
|
fLength = length;
|
||||||
|
fIsPolymorphicCall = isPolymorphicCall;
|
||||||
public int getOffset() {
|
fEnclosingElement = enclosingElement;
|
||||||
return fOffset;
|
}
|
||||||
}
|
|
||||||
|
public int getOffset() {
|
||||||
public int getLength() {
|
return fOffset;
|
||||||
return fLength;
|
}
|
||||||
}
|
|
||||||
|
public int getLength() {
|
||||||
public boolean isPolymorphicCall() {
|
return fLength;
|
||||||
return fIsPolymorphicCall;
|
}
|
||||||
}
|
|
||||||
|
public boolean isPolymorphicCall() {
|
||||||
public ICElement getEnclosingElement() {
|
return fIsPolymorphicCall;
|
||||||
return fEnclosingElement;
|
}
|
||||||
}
|
|
||||||
|
public ICElement getEnclosingElement() {
|
||||||
@Override
|
return fEnclosingElement;
|
||||||
public boolean equals(Object obj) {
|
}
|
||||||
if (!(obj instanceof Match))
|
|
||||||
return false;
|
@Override
|
||||||
Match m = (Match) obj;
|
public boolean equals(Object obj) {
|
||||||
return (fOffset == m.fOffset) && (fLength == m.fLength);
|
if (!(obj instanceof Match))
|
||||||
}
|
return false;
|
||||||
|
Match m = (Match) obj;
|
||||||
@Override
|
return (fOffset == m.fOffset) && (fLength == m.fLength);
|
||||||
public int hashCode() {
|
}
|
||||||
return 31 * fOffset + fLength;
|
|
||||||
}
|
@Override
|
||||||
}
|
public int hashCode() {
|
||||||
|
return 31 * fOffset + fLength;
|
||||||
private static final class MatchesComparator implements Comparator<Match> {
|
}
|
||||||
public int compare(Match m1, Match m2) {
|
}
|
||||||
return m1.getOffset() - m2.getOffset();
|
|
||||||
}
|
private static final class MatchesComparator implements Comparator<Match> {
|
||||||
}
|
public int compare(Match m1, Match m2) {
|
||||||
|
return m1.getOffset() - m2.getOffset();
|
||||||
private final int fOffset;
|
}
|
||||||
private final int fNumber;
|
}
|
||||||
private final String fContent;
|
|
||||||
private final Match[] fMatches;
|
private final int fOffset;
|
||||||
private final static MatchesComparator MATCHES_COMPARATOR = new MatchesComparator();
|
private final int fNumber;
|
||||||
|
private final String fContent;
|
||||||
private LineSearchElement(IIndexFileLocation file, Match[] matches, int number, String content, int offset) {
|
private final Match[] fMatches;
|
||||||
super(file);
|
private final static MatchesComparator MATCHES_COMPARATOR = new MatchesComparator();
|
||||||
fMatches = matches;
|
|
||||||
fNumber = number;
|
private LineSearchElement(IIndexFileLocation file, Match[] matches, int number, String content, int offset) {
|
||||||
// skip whitespace at the beginning
|
super(file);
|
||||||
int index = 0;
|
fMatches = matches;
|
||||||
int length = content.length();
|
fNumber = number;
|
||||||
int firstMatchOffset = matches[0].getOffset();
|
// skip whitespace at the beginning
|
||||||
while (offset < firstMatchOffset && length > 0) {
|
int index = 0;
|
||||||
if (!Character.isWhitespace(content.charAt(index)))
|
int length = content.length();
|
||||||
break;
|
int firstMatchOffset = matches[0].getOffset();
|
||||||
index++;
|
while (offset < firstMatchOffset && length > 0) {
|
||||||
offset++;
|
if (!Character.isWhitespace(content.charAt(index)))
|
||||||
length--;
|
break;
|
||||||
}
|
index++;
|
||||||
fOffset = offset;
|
offset++;
|
||||||
fContent = content.substring(index);
|
length--;
|
||||||
}
|
}
|
||||||
|
fOffset = offset;
|
||||||
public int getOffset() {
|
fContent = content.substring(index);
|
||||||
return fOffset;
|
}
|
||||||
}
|
|
||||||
|
public int getOffset() {
|
||||||
public int getLineNumber() {
|
return fOffset;
|
||||||
return fNumber;
|
}
|
||||||
}
|
|
||||||
|
public int getLineNumber() {
|
||||||
public String getContent() {
|
return fNumber;
|
||||||
return fContent;
|
}
|
||||||
}
|
|
||||||
|
public String getContent() {
|
||||||
public Match[] getMatches() {
|
return fContent;
|
||||||
return fMatches;
|
}
|
||||||
}
|
|
||||||
|
public Match[] getMatches() {
|
||||||
@Override
|
return fMatches;
|
||||||
public String toString() {
|
}
|
||||||
return fNumber + ": " + fContent; //$NON-NLS-1$
|
|
||||||
}
|
@Override
|
||||||
|
public String toString() {
|
||||||
@Override
|
return fNumber + ": " + fContent; //$NON-NLS-1$
|
||||||
public boolean equals(Object obj) {
|
}
|
||||||
if (!(obj instanceof LineSearchElement))
|
|
||||||
return false;
|
@Override
|
||||||
LineSearchElement other = (LineSearchElement) obj;
|
public boolean equals(Object obj) {
|
||||||
return (fOffset == other.fOffset) && (super.equals(obj)) && (fMatches.equals(other.fMatches));
|
if (!(obj instanceof LineSearchElement))
|
||||||
}
|
return false;
|
||||||
|
LineSearchElement other = (LineSearchElement) obj;
|
||||||
@Override
|
return (fOffset == other.fOffset) && (super.equals(obj)) && (fMatches.equals(other.fMatches));
|
||||||
public int hashCode() {
|
}
|
||||||
return fOffset + 31 * (super.hashCode() + 31 * fMatches.hashCode());
|
|
||||||
}
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches) {
|
return fOffset + 31 * (super.hashCode() + 31 * fMatches.hashCode());
|
||||||
// sort matches according to their offsets
|
}
|
||||||
Arrays.sort(matches, MATCHES_COMPARATOR);
|
|
||||||
LineSearchElement[] result = {};
|
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches) {
|
||||||
try {
|
// sort matches according to their offsets
|
||||||
String path = fileLocation.getURI().getPath();
|
Arrays.sort(matches, MATCHES_COMPARATOR);
|
||||||
// read the content of file
|
LineSearchElement[] result = {};
|
||||||
CodeReader reader = new CodeReader(path);
|
|
||||||
result = collectLineElements(reader.buffer, matches, fileLocation);
|
// read the content of file
|
||||||
} catch (IOException e) {
|
FileContent content = FileContent.create(fileLocation);
|
||||||
CUIPlugin.log(e);
|
AbstractCharArray buf = ((InternalFileContent) content).getSource();
|
||||||
}
|
if (buf != null)
|
||||||
return result;
|
result = collectLineElements(buf, matches, fileLocation);
|
||||||
}
|
return result;
|
||||||
|
}
|
||||||
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches,
|
|
||||||
IDocument document) {
|
public static LineSearchElement[] createElements(IIndexFileLocation fileLocation, Match[] matches,
|
||||||
// sort matches according to their offsets
|
IDocument document) {
|
||||||
Arrays.sort(matches, MATCHES_COMPARATOR);
|
// sort matches according to their offsets
|
||||||
// group all matches by lines and create LineSearchElements
|
Arrays.sort(matches, MATCHES_COMPARATOR);
|
||||||
List<LineSearchElement> result = new ArrayList<LineSearchElement>();
|
// group all matches by lines and create LineSearchElements
|
||||||
int firstMatch = 0;
|
List<LineSearchElement> result = new ArrayList<LineSearchElement>();
|
||||||
while (firstMatch < matches.length) {
|
int firstMatch = 0;
|
||||||
try {
|
while (firstMatch < matches.length) {
|
||||||
int lineNumber = document.getLineOfOffset(matches[firstMatch].getOffset());
|
try {
|
||||||
int lineOffset = document.getLineOffset(lineNumber);
|
int lineNumber = document.getLineOfOffset(matches[firstMatch].getOffset());
|
||||||
int lineLength = document.getLineLength(lineNumber);
|
int lineOffset = document.getLineOffset(lineNumber);
|
||||||
int nextlineOffset = lineOffset + lineLength;
|
int lineLength = document.getLineLength(lineNumber);
|
||||||
int nextMatch = firstMatch;
|
int nextlineOffset = lineOffset + lineLength;
|
||||||
int nextMatchOffset = matches[nextMatch].getOffset();
|
int nextMatch = firstMatch;
|
||||||
while (nextMatch < matches.length && nextMatchOffset < nextlineOffset) {
|
int nextMatchOffset = matches[nextMatch].getOffset();
|
||||||
nextMatch++;
|
while (nextMatch < matches.length && nextMatchOffset < nextlineOffset) {
|
||||||
if (nextMatch < matches.length)
|
nextMatch++;
|
||||||
nextMatchOffset = matches[nextMatch].getOffset();
|
if (nextMatch < matches.length)
|
||||||
}
|
nextMatchOffset = matches[nextMatch].getOffset();
|
||||||
int lineMatchesCount = nextMatch - firstMatch;
|
}
|
||||||
Match[] lineMatches = new Match[lineMatchesCount];
|
int lineMatchesCount = nextMatch - firstMatch;
|
||||||
System.arraycopy(matches, firstMatch, lineMatches, 0, lineMatchesCount);
|
Match[] lineMatches = new Match[lineMatchesCount];
|
||||||
String content = document.get(lineOffset, lineLength);
|
System.arraycopy(matches, firstMatch, lineMatches, 0, lineMatchesCount);
|
||||||
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber + 1, content, lineOffset));
|
String content = document.get(lineOffset, lineLength);
|
||||||
firstMatch = nextMatch;
|
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber + 1, content, lineOffset));
|
||||||
} catch (BadLocationException e) {
|
firstMatch = nextMatch;
|
||||||
CUIPlugin.log(e);
|
} catch (BadLocationException e) {
|
||||||
}
|
CUIPlugin.log(e);
|
||||||
}
|
}
|
||||||
return result.toArray(new LineSearchElement[result.size()]);
|
}
|
||||||
}
|
return result.toArray(new LineSearchElement[result.size()]);
|
||||||
|
}
|
||||||
private static LineSearchElement[] collectLineElements(char[] buffer, Match[] matches,
|
|
||||||
IIndexFileLocation fileLocation) {
|
private static LineSearchElement[] collectLineElements(AbstractCharArray buf, Match[] matches,
|
||||||
List<LineSearchElement> result = new ArrayList<LineSearchElement>();
|
IIndexFileLocation fileLocation) {
|
||||||
boolean skipLF = false;
|
List<LineSearchElement> result = new ArrayList<LineSearchElement>();
|
||||||
int lineNumber = 1;
|
boolean skipLF = false;
|
||||||
int lineOffset = 0;
|
int lineNumber = 1;
|
||||||
int lineFirstMatch = -1; // not matched
|
int lineOffset = 0;
|
||||||
int nextMatch = 0;
|
int lineFirstMatch = -1; // not matched
|
||||||
int nextMatchOffset = matches[nextMatch].getOffset();
|
int nextMatch = 0;
|
||||||
for (int pos = 0; pos < buffer.length; pos++) {
|
int nextMatchOffset = matches[nextMatch].getOffset();
|
||||||
char c = buffer[pos];
|
for (int pos = 0; buf.isValidOffset(pos); pos++) {
|
||||||
// consider '\n' and '\r'
|
char c = buf.get(pos);
|
||||||
if (skipLF) {
|
// consider '\n' and '\r'
|
||||||
skipLF = false;
|
if (skipLF) {
|
||||||
if (c == '\n') {
|
skipLF = false;
|
||||||
lineOffset = pos + 1;
|
if (c == '\n') {
|
||||||
continue;
|
lineOffset = pos + 1;
|
||||||
}
|
continue;
|
||||||
}
|
}
|
||||||
if (c == '\n' || c == '\r') {
|
}
|
||||||
// create new LineElement if there were matches
|
if (c == '\n' || c == '\r') {
|
||||||
if (lineFirstMatch != -1) {
|
// create new LineElement if there were matches
|
||||||
int lineLength = pos - lineOffset;
|
if (lineFirstMatch != -1) {
|
||||||
int lineMatchesCount = nextMatch - lineFirstMatch;
|
int lineLength = pos - lineOffset;
|
||||||
Match[] lineMatches = new Match[lineMatchesCount];
|
int lineMatchesCount = nextMatch - lineFirstMatch;
|
||||||
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
|
Match[] lineMatches = new Match[lineMatchesCount];
|
||||||
String lineContent = new String(buffer, lineOffset, lineLength);
|
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
|
||||||
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent,
|
char[] lineChars= new char[lineLength];
|
||||||
lineOffset));
|
buf.arraycopy(lineOffset, lineChars, 0, lineLength);
|
||||||
lineFirstMatch = -1;
|
String lineContent = new String(lineChars);
|
||||||
if (nextMatch >= matches.length)
|
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent,
|
||||||
break;
|
lineOffset));
|
||||||
if (matches[nextMatch].getOffset() < pos)
|
lineFirstMatch = -1;
|
||||||
lineFirstMatch = nextMatch;
|
if (nextMatch >= matches.length)
|
||||||
}
|
break;
|
||||||
lineNumber++;
|
if (matches[nextMatch].getOffset() < pos)
|
||||||
lineOffset = pos + 1;
|
lineFirstMatch = nextMatch;
|
||||||
if (c == '\r')
|
}
|
||||||
skipLF = true;
|
lineNumber++;
|
||||||
continue;
|
lineOffset = pos + 1;
|
||||||
}
|
if (c == '\r')
|
||||||
// compare offset of next match with current position
|
skipLF = true;
|
||||||
if (nextMatchOffset > pos)
|
continue;
|
||||||
continue;
|
}
|
||||||
// next match was reached
|
// compare offset of next match with current position
|
||||||
// check if this match is the first for current line
|
if (nextMatchOffset > pos)
|
||||||
if (lineFirstMatch == -1)
|
continue;
|
||||||
lineFirstMatch = nextMatch;
|
// next match was reached
|
||||||
// goto to next match
|
// check if this match is the first for current line
|
||||||
nextMatch++;
|
if (lineFirstMatch == -1)
|
||||||
if (nextMatch < matches.length) {
|
lineFirstMatch = nextMatch;
|
||||||
// update offset of next match
|
// goto to next match
|
||||||
nextMatchOffset = matches[nextMatch].getOffset();
|
nextMatch++;
|
||||||
} else {
|
if (nextMatch < matches.length) {
|
||||||
// no more matches
|
// update offset of next match
|
||||||
nextMatchOffset = buffer.length;
|
nextMatchOffset = matches[nextMatch].getOffset();
|
||||||
}
|
} else {
|
||||||
}
|
// no more matches
|
||||||
// check if there were matches on the last line
|
break;
|
||||||
if (lineFirstMatch != -1) {
|
}
|
||||||
int lineLength = buffer.length - lineOffset;
|
}
|
||||||
int lineMatchesCount = nextMatch - lineFirstMatch;
|
// check if there were matches on the last line
|
||||||
Match[] lineMatches = new Match[lineMatchesCount];
|
if (lineFirstMatch != -1) {
|
||||||
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
|
int lineLength = buf.getLength() - lineOffset;
|
||||||
String lineContent = new String(buffer, lineOffset, lineLength);
|
int lineMatchesCount = nextMatch - lineFirstMatch;
|
||||||
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent, lineOffset));
|
Match[] lineMatches = new Match[lineMatchesCount];
|
||||||
}
|
System.arraycopy(matches, lineFirstMatch, lineMatches, 0, lineMatchesCount);
|
||||||
return result.toArray(new LineSearchElement[result.size()]);
|
|
||||||
}
|
char[] lineChars= new char[lineLength];
|
||||||
}
|
buf.arraycopy(lineOffset, lineChars, 0, lineLength);
|
||||||
|
String lineContent = new String(lineChars);
|
||||||
|
result.add(new LineSearchElement(fileLocation, lineMatches, lineNumber, lineContent, lineOffset));
|
||||||
|
}
|
||||||
|
return result.toArray(new LineSearchElement[result.size()]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue