mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
fix for 40110 by Jason Montojo
This commit is contained in:
parent
ecfd5b8e3b
commit
860913466b
8 changed files with 294 additions and 2 deletions
|
@ -0,0 +1,108 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 IBM Corporation.
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.ui.tests.text;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
import org.eclipse.jface.text.Document;
|
||||
import org.eclipse.jface.text.rules.IRule;
|
||||
import org.eclipse.jface.text.rules.IToken;
|
||||
import org.eclipse.jface.text.rules.RuleBasedScanner;
|
||||
import org.eclipse.jface.text.rules.Token;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.text.CHeaderRule;
|
||||
|
||||
/**
|
||||
* Tests to verify recognition of #include headers.
|
||||
*/
|
||||
public class CHeaderRuleTest extends TestCase {
|
||||
private static final String HEADER = "header";
|
||||
private IToken fToken;
|
||||
private RuleBasedScanner fScanner;
|
||||
private Document fDocument;
|
||||
|
||||
public CHeaderRuleTest(String name) {
|
||||
super(name);
|
||||
}
|
||||
|
||||
protected void setUp() throws Exception {
|
||||
fToken = new Token(HEADER);
|
||||
fScanner = new RuleBasedScanner();
|
||||
fScanner.setRules(new IRule[] { new CHeaderRule(fToken) });
|
||||
fDocument = new Document();
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite(CHeaderRuleTest.class);
|
||||
}
|
||||
|
||||
public void testHeader() {
|
||||
assertHeader("#include <foo.h>", "<foo.h>", 9);
|
||||
}
|
||||
|
||||
public void testHeader2() {
|
||||
assertHeader("#include <vector>", "<vector>", 9);
|
||||
}
|
||||
|
||||
public void testHeaderExtraSpacesBetween() {
|
||||
assertHeader("#include <foo.h>", "<foo.h>", 12);
|
||||
}
|
||||
|
||||
public void testHeaderExtraSpacesBefore() {
|
||||
assertHeader(" #include <foo.h>", "<foo.h>", 11);
|
||||
}
|
||||
|
||||
public void testBooleanLogic() {
|
||||
assertNotHeader("if (x < 10 && x > 20) return false;", 6);
|
||||
}
|
||||
|
||||
public void testVariableDeclaration() {
|
||||
assertNotHeader("vector<int> foo;", 6);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that there is a header at the given character position.
|
||||
* @param string String to check.
|
||||
* @param header Expected header.
|
||||
* @param position The location of the token which is expected to be a header.
|
||||
*/
|
||||
private void assertHeader(String string, String header, int position) {
|
||||
fDocument.set(string);
|
||||
fScanner.setRange(fDocument, 0, fDocument.getLength());
|
||||
while (position > 0) {
|
||||
fScanner.read();
|
||||
position--;
|
||||
}
|
||||
IToken token = fScanner.nextToken();
|
||||
assertSame(HEADER, token.getData());
|
||||
assertEquals(header.length(), fScanner.getTokenLength());
|
||||
assertEquals(string.indexOf(header), fScanner.getTokenOffset());
|
||||
}
|
||||
|
||||
/**
|
||||
* Verifies that string does not contain a header at the given position.
|
||||
* @param string The String to check.
|
||||
* @param position Offset where scanning should begin.
|
||||
*/
|
||||
private void assertNotHeader(String string, int position) {
|
||||
fDocument.set(string);
|
||||
fScanner.setRange(fDocument, 0, fDocument.getLength());
|
||||
while (position > 0) {
|
||||
fScanner.read();
|
||||
position--;
|
||||
}
|
||||
IToken token = fScanner.nextToken();
|
||||
assertNotSame(HEADER, token.getData());
|
||||
}
|
||||
}
|
|
@ -35,6 +35,7 @@ public class TextTestSuite extends TestSuite {
|
|||
// highlighting tests
|
||||
addTest(SemanticHighlightingTest.suite());
|
||||
addTest(InactiveCodeHighlightingTest.suite());
|
||||
addTest(CHeaderRuleTest.suite());
|
||||
|
||||
// folding tests
|
||||
addTest(FoldingTest.suite());
|
||||
|
|
|
@ -68,6 +68,7 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
|
|||
PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.operators"), ICColorConstants.C_OPERATOR }, { //$NON-NLS-1$
|
||||
PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.braces"), ICColorConstants.C_BRACES }, { //$NON-NLS-1$
|
||||
PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.numbers"), ICColorConstants.C_NUMBER }, { //$NON-NLS-1$
|
||||
PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.headers"), ICColorConstants.C_HEADER }, { //$NON-NLS-1$
|
||||
PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.others"), ICColorConstants.C_DEFAULT }, { //$NON-NLS-1$
|
||||
PreferencesMessages.getString("CEditorPreferencePage.syntaxPage.cCommentTaskTags"), PreferenceConstants.EDITOR_TASK_TAG_COLOR } //$NON-NLS-1$
|
||||
};
|
||||
|
@ -120,6 +121,8 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
|
|||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ICColorConstants.C_NUMBER + "_bold")); //$NON-NLS-1$
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICColorConstants.C_OPERATOR));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ICColorConstants.C_OPERATOR + "_bold")); //$NON-NLS-1$
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, ICColorConstants.C_HEADER));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, ICColorConstants.C_HEADER + "_bold")); //$NON-NLS-1$
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.SUB_WORD_NAVIGATION));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.STRING, CEditor.MATCHING_BRACKETS_COLOR));
|
||||
overlayKeys.add(new OverlayPreferenceStore.OverlayKey(OverlayPreferenceStore.BOOLEAN, CEditor.MATCHING_BRACKETS));
|
||||
|
@ -185,6 +188,9 @@ public class CEditorPreferencePage extends AbstractPreferencePage implements IWo
|
|||
PreferenceConverter.setDefault(store, ICColorConstants.C_BRACES, new RGB(0, 0, 0));
|
||||
store.setDefault(ICColorConstants.C_BRACES + "_bold", false); //$NON-NLS-1$
|
||||
|
||||
PreferenceConverter.setDefault(store, ICColorConstants.C_HEADER, new RGB(42, 0, 255));
|
||||
store.setDefault(ICColorConstants.C_HEADER + "_bold", false); //$NON-NLS-1$
|
||||
|
||||
PreferenceConverter.setDefault(store, ICColorConstants.C_NUMBER, new RGB(0, 0, 0));
|
||||
store.setDefault(ICColorConstants.C_NUMBER + "_bold", false); //$NON-NLS-1$
|
||||
|
||||
|
|
|
@ -97,6 +97,7 @@ CEditorPreferencePage.syntaxPage.strings=Strings
|
|||
CEditorPreferencePage.syntaxPage.operators=Operators
|
||||
CEditorPreferencePage.syntaxPage.braces=Braces
|
||||
CEditorPreferencePage.syntaxPage.numbers=Numbers
|
||||
CEditorPreferencePage.syntaxPage.headers=Headers
|
||||
CEditorPreferencePage.syntaxPage.others=Others
|
||||
CEditorPreferencePage.syntaxPage.cCommentTaskTags=Task Tags
|
||||
CEditorPreferencePage.colorPage.backgroundColor=Bac&kground Color:
|
||||
|
|
|
@ -47,6 +47,7 @@ public final class CCodeScanner extends AbstractCScanner {
|
|||
ICColorConstants.C_OPERATOR,
|
||||
ICColorConstants.C_BRACES,
|
||||
ICColorConstants.C_NUMBER,
|
||||
ICColorConstants.C_HEADER,
|
||||
ICColorConstants.C_DEFAULT,
|
||||
};
|
||||
|
||||
|
@ -101,6 +102,10 @@ public final class CCodeScanner extends AbstractCScanner {
|
|||
NumberRule numberRule = new NumberRule(token);
|
||||
rules.add(numberRule);
|
||||
|
||||
token = getToken(ICColorConstants.C_HEADER);
|
||||
CHeaderRule headerRule = new CHeaderRule(token);
|
||||
rules.add(headerRule);
|
||||
|
||||
token = getToken(ICColorConstants.C_OPERATOR);
|
||||
COperatorRule opRule = new COperatorRule(token);
|
||||
rules.add(opRule);
|
||||
|
|
|
@ -0,0 +1,163 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006 IBM Corporation.
|
||||
* 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
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* IBM Corporation - initial API and implementation
|
||||
*******************************************************************************/
|
||||
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
import org.eclipse.jface.text.rules.ICharacterScanner;
|
||||
import org.eclipse.jface.text.rules.IRule;
|
||||
import org.eclipse.jface.text.rules.IToken;
|
||||
import org.eclipse.jface.text.rules.Token;
|
||||
|
||||
/**
|
||||
* Recognizes headers specified using angle brackets (e.g. #include <stdio.h>).
|
||||
*/
|
||||
public class CHeaderRule implements IRule {
|
||||
|
||||
/** Style token. */
|
||||
private IToken fToken;
|
||||
|
||||
/**
|
||||
* Creates a new CHeaderRule.
|
||||
*
|
||||
* @param token
|
||||
* Style token.
|
||||
*/
|
||||
public CHeaderRule(IToken token) {
|
||||
fToken = token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.jface.text.rules.IRule#evaluate(org.eclipse.jface.text.rules.ICharacterScanner)
|
||||
*/
|
||||
public IToken evaluate(ICharacterScanner scanner) {
|
||||
int current = scanner.read();
|
||||
int lookAhead = 1;
|
||||
int contentLength = 0;
|
||||
|
||||
if (current == '<') {
|
||||
do {
|
||||
current = scanner.read();
|
||||
lookAhead++;
|
||||
if (current == '>') {
|
||||
if (contentLength < 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
// Rewind and check for an #include.
|
||||
seek(scanner, -lookAhead);
|
||||
if (!followsIncludeDirective(scanner)) {
|
||||
return Token.UNDEFINED;
|
||||
}
|
||||
|
||||
seek(scanner, lookAhead);
|
||||
return fToken;
|
||||
}
|
||||
contentLength++;
|
||||
} while (current != ICharacterScanner.EOF && current != '\n');
|
||||
}
|
||||
|
||||
seek(scanner, -lookAhead);
|
||||
return Token.UNDEFINED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Repositions the scanner.
|
||||
*
|
||||
* @param scanner
|
||||
* Scanner.
|
||||
* @param characters
|
||||
* Number of characters to move ahead (if positive) or behind (if
|
||||
* negative).
|
||||
*/
|
||||
private void seek(ICharacterScanner scanner, int characters) {
|
||||
if (characters < 0) {
|
||||
while (characters < 0) {
|
||||
scanner.unread();
|
||||
characters++;
|
||||
}
|
||||
} else {
|
||||
while (characters > 0) {
|
||||
scanner.read();
|
||||
characters--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the previous contents of the scanner is an #include
|
||||
* directive.
|
||||
*
|
||||
* @param scanner
|
||||
* Scanner.
|
||||
* @return true if the previous contents of the scanner is an #include
|
||||
* directive.
|
||||
*/
|
||||
private boolean followsIncludeDirective(ICharacterScanner scanner) {
|
||||
int lookBehind = 0;
|
||||
boolean result = false;
|
||||
|
||||
int current = unread(scanner);
|
||||
lookBehind++;
|
||||
if (Character.isWhitespace(current)) {
|
||||
do {
|
||||
current = unread(scanner);
|
||||
lookBehind++;
|
||||
} while (Character.isWhitespace(current));
|
||||
scanner.read();
|
||||
|
||||
if (searchBackwards(scanner, "#include")) { //$NON-NLS-1$
|
||||
result = true;
|
||||
}
|
||||
}
|
||||
|
||||
seek(scanner, lookBehind);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the given String was the last String read from the
|
||||
* scanner.
|
||||
*
|
||||
* @param scanner
|
||||
* Scanner.
|
||||
* @param string
|
||||
* Expected String.
|
||||
* @return true if the given String was the last String read from the
|
||||
* scanner.
|
||||
*/
|
||||
private boolean searchBackwards(ICharacterScanner scanner, String string) {
|
||||
int offset = 0;
|
||||
for (int i = string.length() - 1; i >= 0; i--) {
|
||||
offset++;
|
||||
if (string.charAt(i) != unread(scanner)) {
|
||||
seek(scanner, offset);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
seek(scanner, offset);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Unreads a single character from the scanner.
|
||||
*
|
||||
* @param scanner
|
||||
* Scanner.
|
||||
* @return the last character read from the scanner.
|
||||
*/
|
||||
private int unread(ICharacterScanner scanner) {
|
||||
scanner.unread();
|
||||
int character = scanner.read();
|
||||
scanner.unread();
|
||||
return character;
|
||||
}
|
||||
|
||||
}
|
|
@ -45,6 +45,7 @@ public final class CppCodeScanner extends AbstractCScanner {
|
|||
ICColorConstants.C_OPERATOR,
|
||||
ICColorConstants.C_BRACES,
|
||||
ICColorConstants.C_NUMBER,
|
||||
ICColorConstants.C_HEADER,
|
||||
ICColorConstants.C_DEFAULT
|
||||
};
|
||||
|
||||
|
@ -105,6 +106,10 @@ public final class CppCodeScanner extends AbstractCScanner {
|
|||
NumberRule numberRule = new NumberRule(token);
|
||||
rules.add(numberRule);
|
||||
|
||||
token = getToken(ICColorConstants.C_HEADER);
|
||||
CHeaderRule headerRule = new CHeaderRule(token);
|
||||
rules.add(headerRule);
|
||||
|
||||
token = getToken(ICColorConstants.C_OPERATOR);
|
||||
COperatorRule opRule = new COperatorRule(token);
|
||||
rules.add(opRule);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2000, 2005 QNX Software Systems and others.
|
||||
* Copyright (c) 2000, 2006 QNX Software Systems 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
|
||||
|
@ -7,6 +7,7 @@
|
|||
*
|
||||
* Contributors:
|
||||
* QNX Software Systems - Initial API and implementation
|
||||
* IBM Corporation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.text;
|
||||
|
||||
|
@ -36,7 +37,9 @@ public interface ICColorConstants {
|
|||
String C_BRACES = "c_braces"; //$NON-NLS-1$
|
||||
/** The color key for numbers. */
|
||||
String C_NUMBER = "c_numbers"; //$NON-NLS-1$
|
||||
/* The color key for everthing in C code for which no other color is specified. */
|
||||
/** The color key for headers. */
|
||||
String C_HEADER = "c_header"; //$NON-NLS-1$
|
||||
/* The color key for everthing in C code for which no other color is specified. */
|
||||
String C_DEFAULT= "c_default"; //$NON-NLS-1$
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Reference in a new issue