diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CPartitionScanner.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionScanner.java
similarity index 98%
rename from core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CPartitionScanner.java
rename to core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionScanner.java
index 87594c786b4..de63bf98a37 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CPartitionScanner.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionScanner.java
@@ -9,7 +9,7 @@
* IBM Corporation - initial API and implementation
* QNX Software System
*******************************************************************************/
-package org.eclipse.cdt.internal.ui.text;
+package org.eclipse.cdt.ui.tests.text;
import java.util.ArrayList;
import java.util.List;
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionerTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionerTest.java
index 6379019245b..6589b7d8fa3 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionerTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CPartitionerTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2006 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
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
@@ -33,42 +34,42 @@ import org.eclipse.cdt.internal.ui.text.CTextTools;
* Derived from JavaPartitionerTest.
*/
public class CPartitionerTest extends TestCase {
-
+
private CTextTools fTextTools;
private Document fDocument;
protected boolean fDocumentPartitioningChanged;
-
-
+
+
public CPartitionerTest(String name) {
super(name);
}
-
+
protected void setUp() {
fTextTools= new CTextTools(new PreferenceStore());
-
+
fDocument= new Document();
IDocumentPartitioner partitioner= fTextTools.createDocumentPartitioner();
partitioner.connect(fDocument);
fDocument.setDocumentPartitioner(partitioner);
fDocument.set("xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\nxxx\n/***/\nxxx");
-
+
fDocumentPartitioningChanged= false;
fDocument.addDocumentPartitioningListener(new IDocumentPartitioningListener() {
public void documentPartitioningChanged(IDocument document) {
fDocumentPartitioningChanged= true;
}
- });
+ });
}
-
+
public static Test suite() {
- return new TestSuite(CPartitionerTest.class);
+ return new TestSuite(CPartitionerTest.class);
}
-
+
protected void tearDown () {
fTextTools.dispose();
fTextTools= null;
-
+
IDocumentPartitioner partitioner= fDocument.getDocumentPartitioner();
partitioner.disconnect();
fDocument= null;
@@ -77,24 +78,24 @@ public class CPartitionerTest extends TestCase {
protected String print(ITypedRegion r) {
return "[" + r.getOffset() + "," + r.getLength() + "," + r.getType() + "]";
}
-
+
protected void checkPartitioning(ITypedRegion[] expectation, ITypedRegion[] result) {
-
+
assertEquals("invalid number of partitions", expectation.length, result.length);
-
+
for (int i= 0; i < expectation.length; i++) {
ITypedRegion e= expectation[i];
ITypedRegion r= result[i];
assertTrue(print(r) + " != " + print(e), r.equals(e));
}
-
+
}
-
+
public void testInitialPartitioning() {
try {
-
+
// "xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\nxxx\n/***/\nxxx"
-
+
ITypedRegion[] result= fDocument.computePartitioning(0, fDocument.getLength());
TypedRegion[] expectation= {
new TypedRegion(0, 4, IDocument.DEFAULT_CONTENT_TYPE),
@@ -107,21 +108,21 @@ public class CPartitionerTest extends TestCase {
new TypedRegion(38, 5, ICPartitions.C_MULTI_LINE_COMMENT),
new TypedRegion(43, 4, IDocument.DEFAULT_CONTENT_TYPE)
};
-
+
checkPartitioning(expectation, result);
} catch (BadLocationException x) {
assertTrue(false);
}
}
-
+
public void testIntraPartitionChange() {
try {
-
+
fDocument.replace(34, 3, "y");
// "xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\ny\n/***/\nxxx");
-
+
assertTrue(!fDocumentPartitioningChanged);
-
+
ITypedRegion[] result= fDocument.computePartitioning(0, fDocument.getLength());
TypedRegion[] expectation= {
new TypedRegion(0, 4, IDocument.DEFAULT_CONTENT_TYPE),
@@ -134,21 +135,21 @@ public class CPartitionerTest extends TestCase {
new TypedRegion(36, 5, ICPartitions.C_MULTI_LINE_COMMENT),
new TypedRegion(41, 4, IDocument.DEFAULT_CONTENT_TYPE)
};
-
+
checkPartitioning(expectation, result);
} catch (BadLocationException x) {
assertTrue(false);
- }
+ }
}
public void testIntraPartitionChange2() {
try {
-
+
fDocument.replace(41, 0, "yyy");
// "xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\nxxx\n/**yyy*/\nxxx");
-
+
// assertTrue(!fDocumentPartitioningChanged);
-
+
ITypedRegion[] result= fDocument.computePartitioning(0, fDocument.getLength());
TypedRegion[] expectation= {
new TypedRegion(0, 4, IDocument.DEFAULT_CONTENT_TYPE),
@@ -161,20 +162,20 @@ public class CPartitionerTest extends TestCase {
new TypedRegion(38, 8, ICPartitions.C_MULTI_LINE_COMMENT),
new TypedRegion(46, 4, IDocument.DEFAULT_CONTENT_TYPE)
};
-
+
checkPartitioning(expectation, result);
} catch (BadLocationException x) {
assertTrue(false);
- }
+ }
}
public void testInsertNewPartition() {
try {
-
+
fDocument.replace(35, 1, "/***/");
// "xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\nx/***/x\n/***/\nxxx");
-
+
assertTrue(fDocumentPartitioningChanged);
-
+
ITypedRegion[] result= fDocument.computePartitioning(0, fDocument.getLength());
TypedRegion[] expectation= {
new TypedRegion(0, 4, IDocument.DEFAULT_CONTENT_TYPE),
@@ -189,20 +190,20 @@ public class CPartitionerTest extends TestCase {
new TypedRegion(42, 5, ICPartitions.C_MULTI_LINE_COMMENT),
new TypedRegion(47, 4, IDocument.DEFAULT_CONTENT_TYPE)
};
-
+
checkPartitioning(expectation, result);
} catch (BadLocationException x) {
assertTrue(false);
- }
- }
+ }
+ }
public void testInsertStringPartition() {
try {
-
+
fDocument.replace(35, 1, "\"yyy\"");
// "xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\nx\"yyy\"x\n/***/\nxxx");
-
+
assertTrue(fDocumentPartitioningChanged);
-
+
ITypedRegion[] result= fDocument.computePartitioning(0, fDocument.getLength());
TypedRegion[] expectation= {
new TypedRegion(0, 4, IDocument.DEFAULT_CONTENT_TYPE),
@@ -217,20 +218,20 @@ public class CPartitionerTest extends TestCase {
new TypedRegion(42, 5, ICPartitions.C_MULTI_LINE_COMMENT),
new TypedRegion(47, 4, IDocument.DEFAULT_CONTENT_TYPE)
};
-
+
checkPartitioning(expectation, result);
} catch (BadLocationException x) {
assertTrue(false);
- }
- }
+ }
+ }
public void testInsertCharacterPartition() {
try {
-
+
fDocument.replace(35, 1, "'y'");
// "xxx\n/*xxx*/\nxxx\n/**xxx*/\nxxx\n/**/\nx\"yyy\"x\n/***/\nxxx");
-
+
assertTrue(fDocumentPartitioningChanged);
-
+
ITypedRegion[] result= fDocument.computePartitioning(0, fDocument.getLength());
TypedRegion[] expectation= {
new TypedRegion(0, 4, IDocument.DEFAULT_CONTENT_TYPE),
@@ -245,22 +246,50 @@ public class CPartitionerTest extends TestCase {
new TypedRegion(40, 5, ICPartitions.C_MULTI_LINE_COMMENT),
new TypedRegion(45, 4, IDocument.DEFAULT_CONTENT_TYPE)
};
-
+
checkPartitioning(expectation, result);
} catch (BadLocationException x) {
assertTrue(false);
- }
- }
+ }
+ }
+ public void testInsertPreprocessorPartition() {
+ try {
+
+ fDocument.replace(4, 0, " # include
true
C++ keywords are used, else C keywords
+ */
+ public CPreprocessorScanner(IColorManager manager, IPreferenceStore store, boolean isCpp) {
+ super(manager, store);
+ fIsCpp= isCpp;
+ initialize();
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.AbstractCScanner#createRules()
+ */
+ protected List createRules() {
+
+ Token defaultToken= getToken(ICColorConstants.PP_DEFAULT);
+
+ List rules= new ArrayList();
+ Token token;
+
+ // Add generic white space rule.
+ rules.add(new WhitespaceRule(new CWhitespaceDetector()));
+
+ token= getToken(ICColorConstants.PP_DIRECTIVE);
+ PreprocessorRule preprocessorRule = new PreprocessorRule(new CWordDetector(), token);
+ Iterator iter;
+ if (fIsCpp) {
+ iter = ParserFactory.getKeywordSet( KeywordSetKey.PP_DIRECTIVE, ParserLanguage.CPP ).iterator();
+ } else {
+ iter = ParserFactory.getKeywordSet( KeywordSetKey.PP_DIRECTIVE, ParserLanguage.C ).iterator();
+ }
+ while( iter.hasNext() )
+ preprocessorRule.addWord((String) iter.next(), token);
+
+ // add ## operator
+ preprocessorRule.addWord("##", token); //$NON-NLS-1$
+ rules.add(preprocessorRule);
+
+ // Add word rule for keywords, types, and constants.
+ WordRule wordRule= new WordRule(new CWordDetector(), defaultToken);
+
+ token= getToken(ICColorConstants.C_KEYWORD);
+ if (fIsCpp) {
+ iter = ParserFactory.getKeywordSet( KeywordSetKey.KEYWORDS, ParserLanguage.CPP ).iterator();
+ } else {
+ iter = ParserFactory.getKeywordSet( KeywordSetKey.KEYWORDS, ParserLanguage.C ).iterator();
+ }
+ while( iter.hasNext() )
+ wordRule.addWord((String) iter.next(), token);
+
+ token= getToken(ICColorConstants.C_TYPE);
+ iter = ParserFactory.getKeywordSet( KeywordSetKey.TYPES, ParserLanguage.C ).iterator();
+ while( iter.hasNext() )
+ wordRule.addWord((String) iter.next(), token);
+ rules.add(wordRule);
+
+ token = getToken(ICColorConstants.PP_HEADER);
+ CHeaderRule headerRule = new CHeaderRule(token);
+ rules.add(headerRule);
+
+ token = getToken(ICColorConstants.C_SINGLE_LINE_COMMENT);
+ IRule lineCommentRule = new EndOfLineRule("//", token, '\\', true); //$NON-NLS-1$
+ rules.add(lineCommentRule);
+
+ token = getToken(ICColorConstants.C_MULTI_LINE_COMMENT);
+ IRule blockCommentRule = new MultiLineRule("/*", "*/", token, '\\'); //$NON-NLS-1$ //$NON-NLS-2$
+ rules.add(blockCommentRule);
+
+ token = getToken(ICColorConstants.C_STRING);
+ IRule stringRule = new PatternRule("\"", "\"", token, '\\', true, true, true); //$NON-NLS-1$ //$NON-NLS-2$
+ rules.add(stringRule);
+
+ token = getToken(ICColorConstants.C_STRING);
+ IRule charRule = new PatternRule("'", "'", token, '\\', true, true, true); //$NON-NLS-1$ //$NON-NLS-2$
+ rules.add(charRule);
+
+ setDefaultReturnToken(defaultToken);
+ return rules;
+ }
+
+ /*
+ * @see org.eclipse.cdt.internal.ui.text.AbstractCScanner#getTokenProperties()
+ */
+ protected String[] getTokenProperties() {
+ return fgTokenProperties;
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
index aa4d425b94b..609340a7276 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CSourceViewerConfiguration.java
@@ -118,6 +118,24 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
return fTextTools.getStringScanner();
}
+ /**
+ * Returns the C preprocessor scanner for this configuration.
+ *
+ * @return the C preprocessor scanner
+ */
+ protected RuleBasedScanner getCPreprocessorScanner() {
+ return fTextTools.getCPreprocessorScanner();
+ }
+
+ /**
+ * Returns the C++ preprocessor scanner for this configuration.
+ *
+ * @return the C++ preprocessor scanner
+ */
+ protected RuleBasedScanner getCppPreprocessorScanner() {
+ return fTextTools.getCppPreprocessorScanner();
+ }
+
/**
* Returns the color manager for this configuration.
*
@@ -153,6 +171,7 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
presenter.setInformationProvider(provider, ICPartitions.C_SINGLE_LINE_COMMENT);
presenter.setInformationProvider(provider, ICPartitions.C_STRING);
presenter.setInformationProvider(provider, ICPartitions.C_CHARACTER);
+ presenter.setInformationProvider(provider, ICPartitions.C_PREPROCESSOR);
presenter.setSizeConstraints(20, 20, true, false);
presenter.setRestoreInformationControlBounds(getSettings("outline_presenter_bounds"), true, true); //$NON-NLS-1$
return presenter;
@@ -167,8 +186,9 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
reconciler.setDocumentPartitioning(getConfiguredDocumentPartitioning(sourceViewer));
RuleBasedScanner scanner = null;
+ ILanguage language= null;
if(sourceViewer instanceof CSourceViewer) {
- ILanguage language = ((CSourceViewer)sourceViewer).getLanguage();
+ language = ((CSourceViewer)sourceViewer).getLanguage();
if (language instanceof GPPLanguage) {
scanner = fTextTools.getCppCodeScanner();
} else if (language instanceof GCCLanguage) {
@@ -206,6 +226,18 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
reconciler.setDamager(dr, ICPartitions.C_CHARACTER);
reconciler.setRepairer(dr, ICPartitions.C_CHARACTER);
+ if (language instanceof GPPLanguage) {
+ dr= new DefaultDamagerRepairer(getCppPreprocessorScanner());
+ } else if (language instanceof GCCLanguage) {
+ dr= new DefaultDamagerRepairer(getCPreprocessorScanner());
+ } else {
+ dr= null;
+ }
+ if (dr != null) {
+ reconciler.setDamager(new PartitionDamager(), ICPartitions.C_PREPROCESSOR);
+ reconciler.setRepairer(dr, ICPartitions.C_PREPROCESSOR);
+ }
+
return reconciler;
}
@@ -400,7 +432,8 @@ public class CSourceViewerConfiguration extends TextSourceViewerConfiguration {
ICPartitions.C_MULTI_LINE_COMMENT,
ICPartitions.C_SINGLE_LINE_COMMENT,
ICPartitions.C_STRING,
- ICPartitions.C_CHARACTER};
+ ICPartitions.C_CHARACTER,
+ ICPartitions.C_PREPROCESSOR};
}
/**
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CTextTools.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CTextTools.java
index f6baedc107f..b9f6c44333c 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CTextTools.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CTextTools.java
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software System
+ * Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
@@ -51,12 +52,16 @@ public class CTextTools {
private CppCodeScanner fCppCodeScanner;
/** The C partitions scanner */
private FastCPartitionScanner fPartitionScanner;
- /** The Java multiline comment scanner */
+ /** The C multiline comment scanner */
private CCommentScanner fMultilineCommentScanner;
- /** The Java singleline comment scanner */
+ /** The C singleline comment scanner */
private CCommentScanner fSinglelineCommentScanner;
- /** The Java string scanner */
+ /** The C string scanner */
private SingleTokenCScanner fStringScanner;
+ /** The C preprocessor scanner */
+ private CPreprocessorScanner fCPreprocessorScanner;
+ /** The C++ preprocessor scanner */
+ private CPreprocessorScanner fCppPreprocessorScanner;
/** The preference store */
private IPreferenceStore fPreferenceStore;
@@ -99,6 +104,8 @@ public class CTextTools {
fMultilineCommentScanner= new CCommentScanner(fColorManager, store, coreStore, ICColorConstants.C_MULTI_LINE_COMMENT);
fSinglelineCommentScanner= new CCommentScanner(fColorManager, store, coreStore, ICColorConstants.C_SINGLE_LINE_COMMENT);
fStringScanner= new SingleTokenCScanner(fColorManager, store, ICColorConstants.C_STRING);
+ fCPreprocessorScanner= new CPreprocessorScanner(fColorManager, store, false);
+ fCppPreprocessorScanner= new CPreprocessorScanner(fColorManager, store, true);
fPreferenceStore = store;
fPreferenceStore.addPropertyChangeListener(fPreferenceListener);
@@ -190,7 +197,8 @@ public class CTextTools {
ICPartitions.C_MULTI_LINE_COMMENT,
ICPartitions.C_SINGLE_LINE_COMMENT,
ICPartitions.C_STRING,
- ICPartitions.C_CHARACTER
+ ICPartitions.C_CHARACTER,
+ ICPartitions.C_PREPROCESSOR
};
return new FastPartitioner(getPartitionScanner(), types);
@@ -215,14 +223,31 @@ public class CTextTools {
}
/**
- * Returns a scanner which is configured to scan Java strings.
+ * Returns a scanner which is configured to scan C strings.
*
- * @return a Java string scanner
+ * @return a C string scanner
*/
public RuleBasedScanner getStringScanner() {
return fStringScanner;
}
+ /**
+ * Returns a scanner which is configured to scan C preprocessor directives.
+ *
+ * @return a C preprocessor directives scanner
+ */
+ public RuleBasedScanner getCPreprocessorScanner() {
+ return fCPreprocessorScanner;
+ }
+
+ /**
+ * Returns a scanner which is configured to scan C++ preprocessor directives.
+ *
+ * @return a C++ preprocessor directives scanner
+ */
+ public RuleBasedScanner getCppPreprocessorScanner() {
+ return fCppPreprocessorScanner;
+ }
/**
* Determines whether the preference change encoded by the given event
@@ -236,7 +261,8 @@ public class CTextTools {
fCppCodeScanner.affectsBehavior(event) ||
fMultilineCommentScanner.affectsBehavior(event) ||
fSinglelineCommentScanner.affectsBehavior(event) ||
- fStringScanner.affectsBehavior(event);
+ fStringScanner.affectsBehavior(event) ||
+ fCPreprocessorScanner.affectsBehavior(event);
}
/**
@@ -256,6 +282,10 @@ public class CTextTools {
fSinglelineCommentScanner.adaptToPreferenceChange(event);
if (fStringScanner.affectsBehavior(event))
fStringScanner.adaptToPreferenceChange(event);
+ if (fCPreprocessorScanner.affectsBehavior(event)) {
+ fCPreprocessorScanner.adaptToPreferenceChange(event);
+ fCppPreprocessorScanner.adaptToPreferenceChange(event);
+ }
}
/**
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CppCodeScanner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CppCodeScanner.java
index 3d0b38a0842..5c153bbd80e 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CppCodeScanner.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/CppCodeScanner.java
@@ -19,6 +19,7 @@ import java.util.List;
import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WhitespaceRule;
import org.eclipse.jface.text.rules.WordRule;
import org.eclipse.jface.util.PropertyChangeEvent;
@@ -26,6 +27,7 @@ import org.eclipse.cdt.core.parser.KeywordSetKey;
import org.eclipse.cdt.core.parser.ParserFactory;
import org.eclipse.cdt.core.parser.ParserLanguage;
+import org.eclipse.cdt.internal.ui.text.util.CWhitespaceDetector;
import org.eclipse.cdt.internal.ui.text.util.CWordDetector;
@@ -41,11 +43,9 @@ public final class CppCodeScanner extends AbstractCScanner {
private static String[] fgTokenProperties= {
ICColorConstants.C_KEYWORD,
ICColorConstants.C_TYPE,
- ICColorConstants.C_STRING,
ICColorConstants.C_OPERATOR,
ICColorConstants.C_BRACES,
ICColorConstants.C_NUMBER,
- ICColorConstants.C_HEADER,
ICColorConstants.C_DEFAULT
};
@@ -74,9 +74,8 @@ public final class CppCodeScanner extends AbstractCScanner {
Token token;
// Add generic whitespace rule.
- //rules.add(new WhitespaceRule(new CWhitespaceDetector()));
+ rules.add(new WhitespaceRule(new CWhitespaceDetector()));
-
// Add word rule for keywords, types, and constants.
token= getToken(ICColorConstants.C_DEFAULT);
WordRule wordRule= new WordRule(new CWordDetector(), token);
@@ -93,23 +92,10 @@ public final class CppCodeScanner extends AbstractCScanner {
wordRule.addWord(fgConstants[i], token);
rules.add(wordRule);
- token = getToken(ICColorConstants.C_TYPE);
- PreprocessorRule preprocessorRule = new PreprocessorRule(new CWordDetector(), token);
- iter = ParserFactory.getKeywordSet( KeywordSetKey.PP_DIRECTIVE, ParserLanguage.CPP ).iterator();
-
- while( iter.hasNext() )
- preprocessorRule.addWord((String) iter.next(), token);
-
- rules.add(preprocessorRule);
-
token = getToken(ICColorConstants.C_NUMBER);
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);
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/FastCPartitionScanner.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/FastCPartitionScanner.java
index 3dcb2932b6a..f9bc09de982 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/FastCPartitionScanner.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/FastCPartitionScanner.java
@@ -13,6 +13,7 @@
package org.eclipse.cdt.internal.ui.text;
+import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.rules.ICharacterScanner;
import org.eclipse.jface.text.rules.IPartitionTokenScanner;
@@ -24,9 +25,9 @@ import org.eclipse.cdt.ui.text.ICPartitions;
/**
* This scanner recognizes the C multi line comments, C single line comments,
- * C strings and C characters.
+ * C strings, C characters and C preprocessor directives.
*/
-public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitions {
+public final class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitions {
// states
private static final int CCODE= 0;
@@ -34,17 +35,19 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
private static final int MULTI_LINE_COMMENT= 2;
private static final int CHARACTER= 3;
private static final int STRING= 4;
+ private static final int PREPROCESSOR= 5;
+ private static final int PREPROCESSOR_MULTI_LINE_COMMENT= 6;
// beginning of prefixes and postfixes
private static final int NONE= 0;
- private static final int BACKSLASH= 1; // postfix for STRING and CHARACTER
+ private static final int BACKSLASH= 1; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
private static final int SLASH= 2; // prefix for SINGLE_LINE or MULTI_LINE
private static final int SLASH_STAR= 3; // prefix for MULTI_LINE_COMMENT
private static final int STAR= 4; // postfix for MULTI_LINE_COMMENT
private static final int CARRIAGE_RETURN=5; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
+ private static final int BACKSLASH_CR= 6; // postfix for STRING, CHARACTER and SINGLE_LINE_COMMENT
/** The scanner. */
-// private final BufferedRuleBasedScanner fScanner= new BufferedRuleBasedScanner(1000);
private final BufferedDocumentScanner fScanner= new BufferedDocumentScanner(1000); // faster implementation
/** The offset of the last returned token. */
@@ -58,62 +61,213 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
private int fLast;
/** The amount of characters already read on first call to nextToken(). */
private int fPrefixLength;
+ /** Indicate whether current char is first non-whitespace char on the line*/
+ private boolean fFirstCharOnLine= true;
+
+ // emulate CPartitionScanner
+ private boolean fEmulate= false;
+ private int fCCodeOffset;
+ private int fCCodeLength;
private final IToken[] fTokens= new IToken[] {
new Token(null),
new Token(C_SINGLE_LINE_COMMENT),
new Token(C_MULTI_LINE_COMMENT),
new Token(C_CHARACTER),
- new Token(C_STRING)
+ new Token(C_STRING),
+ new Token(C_PREPROCESSOR),
+ new Token(C_PREPROCESSOR)
};
+ public FastCPartitionScanner(boolean emulate) {
+ fEmulate= emulate;
+ }
+
+ public FastCPartitionScanner() {
+ this(false);
+ }
+
/*
* @see org.eclipse.jface.text.rules.ITokenScanner#nextToken()
*/
public IToken nextToken() {
+
+ // emulate CPartitionScanner
+ if (fEmulate) {
+ if (fCCodeOffset != -1 && fTokenOffset + fTokenLength != fCCodeOffset + fCCodeLength) {
+ fTokenOffset += fTokenLength;
+ return fTokens[CCODE];
+ } else {
+ fCCodeOffset= -1;
+ fCCodeLength= 0;
+ }
+ }
+
fTokenOffset += fTokenLength;
fTokenLength= fPrefixLength;
- final char[][] delimiters = fScanner.getLegalLineDelimiters();
-
while (true) {
final int ch= fScanner.read();
-
- if (ch == ICharacterScanner.EOF) {
+
+ final boolean isFirstCharOnLine= fFirstCharOnLine;
+ if (fFirstCharOnLine && ch != ' ' && ch != '\t') {
+ fFirstCharOnLine= false;
+ }
+ // characters
+ switch (ch) {
+ case ICharacterScanner.EOF:
if (fTokenLength > 0) {
fLast= NONE; // ignore last
return preFix(fState, CCODE, NONE, 0);
+ } else {
+ fLast= NONE;
+ fPrefixLength= 0;
+ return Token.EOF;
}
- fLast= NONE;
- fPrefixLength= 0;
- return Token.EOF;
- }
-
- // detect if we're at the end of the line
- final int delim = detectLineDelimiter(ch, fScanner, delimiters);
- if (delim != -1) {
- final int len = delimiters[delim].length;
- if (len > 1) {
- // adjust the token length if the delimiter was 2 or more chars
- fTokenLength += (len - 1);
- }
+
+ case '\r':
+ fFirstCharOnLine= true;
+ if (!fEmulate && fLast == BACKSLASH) {
+ fLast= BACKSLASH_CR;
+ fTokenLength++;
+ continue;
+ } else if (!fEmulate && fLast != CARRIAGE_RETURN) {
+ fLast= CARRIAGE_RETURN;
+ fTokenLength++;
+ continue;
+ } else {
+ // fEmulate || fLast == CARRIAGE_RETURN
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+ case PREPROCESSOR:
+ if (fTokenLength > 0) {
+ IToken token= fTokens[fState];
+
+ // emulate CPartitionScanner
+ if (fEmulate) {
+ fTokenLength++;
+ fLast= NONE;
+ fPrefixLength= 0;
+ } else {
+ fLast= CARRIAGE_RETURN;
+ fPrefixLength= 1;
+ }
+
+ fState= CCODE;
+ return token;
+
+ } else {
+ consume();
+ continue;
+ }
+
+ default:
+ consume();
+ continue;
+ }
+ }
+
+ case '\\':
+ if (fLast == BACKSLASH) {
+ consume();
+ continue;
+ }
+ break;
+
+ case '\n':
+ fFirstCharOnLine= true;
switch (fState) {
case SINGLE_LINE_COMMENT:
case CHARACTER:
case STRING:
+ case PREPROCESSOR:
// assert(fTokenLength > 0);
// if last char was a backslash then we have an escaped line
- if (fLast != BACKSLASH) {
+ if (fLast != BACKSLASH && fLast != BACKSLASH_CR) {
return postFix(fState);
}
- // FALLTHROUGH
default:
consume();
continue;
}
+ default:
+ if (!fEmulate && fLast == CARRIAGE_RETURN) {
+ switch (fState) {
+ case SINGLE_LINE_COMMENT:
+ case CHARACTER:
+ case STRING:
+
+ int last;
+ int newState;
+ switch (ch) {
+ case '/':
+ last= SLASH;
+ newState= CCODE;
+ break;
+
+ case '*':
+ last= STAR;
+ newState= CCODE;
+ break;
+
+ case '\'':
+ last= NONE;
+ newState= CHARACTER;
+ break;
+
+ case '"':
+ last= NONE;
+ newState= STRING;
+ break;
+
+ case '\r':
+ last= CARRIAGE_RETURN;
+ newState= CCODE;
+ break;
+
+ case '\\':
+ last= BACKSLASH;
+ newState= CCODE;
+ break;
+
+ default:
+ last= NONE;
+ newState= CCODE;
+ break;
+ }
+
+ fLast= NONE; // ignore fLast
+ return preFix(fState, newState, last, 1);
+
+ case CCODE:
+ if (ch == '#' && isFirstCharOnLine) {
+ fLast= NONE; // ignore fLast
+ int column= fScanner.getColumn() - 1;
+ fTokenLength -= column;
+ if (fTokenLength > 0) {
+ return preFix(fState, PREPROCESSOR, NONE, column + 1);
+ } else {
+ preFix(fState, PREPROCESSOR, NONE, column + 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+ }
+ break;
+
+ case PREPROCESSOR:
+ fLast= NONE; // ignore fLast
+ return preFix(fState, CCODE, NONE, 1);
+
+ default:
+ break;
+ }
+ }
}
// states
@@ -124,69 +278,143 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
if (fLast == SLASH) {
if (fTokenLength - getLastLength(fLast) > 0) {
return preFix(CCODE, SINGLE_LINE_COMMENT, NONE, 2);
- }
- preFix(CCODE, SINGLE_LINE_COMMENT, NONE, 2);
- fTokenOffset += fTokenLength;
- fTokenLength= fPrefixLength;
- break;
+ } else {
+ preFix(CCODE, SINGLE_LINE_COMMENT, NONE, 2);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+ } else {
+ fTokenLength++;
+ fLast= SLASH;
+ break;
}
- fTokenLength++;
- fLast= SLASH;
- break;
case '*':
if (fLast == SLASH) {
- if (fTokenLength - getLastLength(fLast) > 0)
+ if (fTokenLength - getLastLength(fLast) > 0) {
return preFix(CCODE, MULTI_LINE_COMMENT, SLASH_STAR, 2);
-
- preFix(CCODE, MULTI_LINE_COMMENT, SLASH_STAR, 2);
- fTokenOffset += fTokenLength;
- fTokenLength= fPrefixLength;
- break;
+ } else {
+ preFix(CCODE, MULTI_LINE_COMMENT, SLASH_STAR, 2);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+ } else {
+ consume();
+ break;
}
- consume();
- break;
case '\'':
fLast= NONE; // ignore fLast
if (fTokenLength > 0) {
return preFix(CCODE, CHARACTER, NONE, 1);
+ } else {
+ preFix(CCODE, CHARACTER, NONE, 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
}
- preFix(CCODE, CHARACTER, NONE, 1);
- fTokenOffset += fTokenLength;
- fTokenLength= fPrefixLength;
- break;
case '"':
fLast= NONE; // ignore fLast
if (fTokenLength > 0 ) {
return preFix(CCODE, STRING, NONE, 1);
+ } else {
+ preFix(CCODE, STRING, NONE, 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
}
- preFix(CCODE, STRING, NONE, 1);
- fTokenOffset += fTokenLength;
- fTokenLength= fPrefixLength;
- break;
-
+
+ case '#':
+ if (!fEmulate && isFirstCharOnLine) {
+ int column= fScanner.getColumn() - 1;
+ fTokenLength -= column;
+ if (fTokenLength > 0) {
+ return preFix(fState, PREPROCESSOR, NONE, column + 1);
+ } else {
+ preFix(fState, PREPROCESSOR, NONE, column + 1);
+ fTokenOffset += fTokenLength;
+ fTokenLength= fPrefixLength;
+ break;
+ }
+ }
+ // fallthrough
default:
consume();
break;
}
break;
-
+
case SINGLE_LINE_COMMENT:
- switch (ch) {
- case '\\':
+ switch (ch) {
+ case '\\':
fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
fTokenLength++;
break;
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case PREPROCESSOR:
+ switch (ch) {
+ case '\\':
+ fLast= (fLast == BACKSLASH) ? NONE : BACKSLASH;
+ fTokenLength++;
+ break;
+
+ case '/':
+ if (fLast == SLASH) {
+ consume();
+ break;
+ } else {
+ fTokenLength++;
+ fLast= SLASH;
+ break;
+ }
+
+ case '*':
+ if (fLast == SLASH) {
+ fState= PREPROCESSOR_MULTI_LINE_COMMENT;
+ consume();
+ break;
+ } else {
+ consume();
+ break;
+ }
+
+ default:
+ consume();
+ break;
+ }
+ break;
+
+ case PREPROCESSOR_MULTI_LINE_COMMENT:
+ switch (ch) {
+ case '*':
+ fTokenLength++;
+ fLast= STAR;
+ break;
+
+ case '/':
+ if (fLast == STAR) {
+ fState= PREPROCESSOR;
+ consume();
+ }
+ break;
+
default:
consume();
- break;
+ break;
}
break;
-
+
case MULTI_LINE_COMMENT:
switch (ch) {
case '*':
@@ -197,9 +425,10 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
case '/':
if (fLast == STAR) {
return postFix(MULTI_LINE_COMMENT);
+ } else {
+ consume();
+ break;
}
- consume();
- break;
default:
consume();
@@ -218,9 +447,10 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
if (fLast != BACKSLASH) {
return postFix(STRING);
+ } else {
+ consume();
+ break;
}
- consume();
- break;
default:
consume();
@@ -239,9 +469,10 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
if (fLast != BACKSLASH) {
return postFix(CHARACTER);
+ } else {
+ consume();
+ break;
}
- consume();
- break;
default:
consume();
@@ -252,46 +483,6 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
}
}
- /**
- * returns index of longest matching element in delimiters
- */
- private static final int detectLineDelimiter(final int ch, final ICharacterScanner scanner, final char[][] delimiters) {
- int longestDelimiter = -1;
- int maxLen = 0;
- for (int i = 0; i < delimiters.length; i++) {
- final char[] delim = delimiters[i];
- if (ch == delim[0]) {
- final int len = delim.length;
- if (len > maxLen && (len == 1 || sequenceDetected(scanner, delim, 1, len))) {
- maxLen = len;
- longestDelimiter = i;
- }
- }
- }
- return longestDelimiter;
- }
-
- /**
- * true
if sequence matches between beginIndex (inclusive) and endIndex (exclusive)
- */
- private static final boolean sequenceDetected(final ICharacterScanner scanner, final char[] sequence, final int beginIndex, final int endIndex) {
- int charsRead = 0;
- for (int i = beginIndex; i < endIndex; ++i) {
- final int c = scanner.read();
- if (c != ICharacterScanner.EOF) {
- ++charsRead;
- }
- if (c != sequence[i]) {
- // Non-matching character detected, rewind the scanner back to the start.
- for (; charsRead > 0; --charsRead) {
- scanner.unread();
- }
- return false;
- }
- }
- return true;
- }
-
private static final int getLastLength(int last) {
switch (last) {
default:
@@ -307,6 +498,7 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
return 1;
case SLASH_STAR:
+ case BACKSLASH_CR:
return 2;
}
@@ -326,12 +518,25 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
}
private final IToken preFix(int state, int newState, int last, int prefixLength) {
- fTokenLength -= getLastLength(fLast);
- fLast= last;
- fPrefixLength= prefixLength;
- IToken token= fTokens[state];
- fState= newState;
- return token;
+ // emulate CPartitionScanner
+ if (fEmulate && state == CCODE && (fTokenLength - getLastLength(fLast) > 0)) {
+ fTokenLength -= getLastLength(fLast);
+ fCCodeOffset= fTokenOffset;
+ fCCodeLength= fTokenLength;
+ fTokenLength= 1;
+ fState= newState;
+ fPrefixLength= prefixLength;
+ fLast= last;
+ return fTokens[state];
+
+ } else {
+ fTokenLength -= getLastLength(fLast);
+ fLast= last;
+ fPrefixLength= prefixLength;
+ IToken token= fTokens[state];
+ fState= newState;
+ return token;
+ }
}
private static int getState(String contentType) {
@@ -350,6 +555,9 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
else if (contentType.equals(C_CHARACTER))
return CHARACTER;
+
+ else if (contentType.equals(C_PREPROCESSOR))
+ return PREPROCESSOR;
else
return CCODE;
@@ -373,6 +581,18 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
fState= getState(contentType);
}
+ try {
+ int column= fScanner.getColumn();
+ fFirstCharOnLine= column == 0 || document.get(offset-column, column).trim().length() == 0;
+ } catch (BadLocationException exc) {
+ fFirstCharOnLine= true;
+ }
+
+ // emulate CPartitionScanner
+ if (fEmulate) {
+ fCCodeOffset= -1;
+ fCCodeLength= 0;
+ }
}
/*
@@ -387,6 +607,18 @@ public class FastCPartitionScanner implements IPartitionTokenScanner, ICPartitio
fLast= NONE;
fState= CCODE;
+ try {
+ int column= fScanner.getColumn();
+ fFirstCharOnLine= column == 0 || document.get(offset-column, column).trim().length() == 0;
+ } catch (BadLocationException exc) {
+ fFirstCharOnLine= true;
+ }
+
+ // emulate CPartitionScanner
+ if (fEmulate) {
+ fCCodeOffset= -1;
+ fCCodeLength= 0;
+ }
}
/*
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICColorConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICColorConstants.java
index 8f3466b1db2..7a6ec0768fa 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICColorConstants.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/ICColorConstants.java
@@ -18,30 +18,32 @@ package org.eclipse.cdt.internal.ui.text;
*/
public interface ICColorConstants {
- /* The prefix all color constants start with */
- String PREFIX= "c_"; //$NON-NLS-1$
-
- /* The color key for multi-line comments in C code. */
+ /** The color key for multi-line comments in C code. */
String C_MULTI_LINE_COMMENT= "c_multi_line_comment"; //$NON-NLS-1$
- /* The color key for single-line comments in C code. */
+ /** The color key for single-line comments in C code. */
String C_SINGLE_LINE_COMMENT= "c_single_line_comment"; //$NON-NLS-1$
- /* The color key for keywords in C code. */
+ /** The color key for keywords in C code. */
String C_KEYWORD= "c_keyword"; //$NON-NLS-1$
- /* The color key for builtin types in C code. */
+ /** The color key for builtin types in C code. */
String C_TYPE= "c_type"; //$NON-NLS-1$
- /* The color key for string and character literals in C code. */
+ /** The color key for string and character literals in C code. */
String C_STRING= "c_string"; //$NON-NLS-1$
/** The color key for operators. */
- String C_OPERATOR = "c_operators"; //$NON-NLS-1$
+ String C_OPERATOR= "c_operators"; //$NON-NLS-1$
/** The color key for braces. */
- String C_BRACES = "c_braces"; //$NON-NLS-1$
+ 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 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_NUMBER= "c_numbers"; //$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$
-
+
+ /** The color key for preprocessor directives. */
+ String PP_DIRECTIVE= "pp_directive"; //$NON-NLS-1$
+ /** The color key for preprocessor text not colored otherwise. */
+ String PP_DEFAULT= "pp_default"; //$NON-NLS-1$
+ /** The color key for preprocessor include files. */
+ String PP_HEADER= "pp_header"; //$NON-NLS-1$
+
/**
* The color key for task tags in C comments
* (value "c_comment_task_tag"
).
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PartitionDamager.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PartitionDamager.java
new file mode 100644
index 00000000000..06099b8246c
--- /dev/null
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PartitionDamager.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * Copyright (c) 2006 Wind River Systems, Inc. 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anton Leherbauer (Wind River Systems) - initial API and implementation
+ *******************************************************************************/
+
+package org.eclipse.cdt.internal.ui.text;
+
+import org.eclipse.jface.text.DocumentEvent;
+import org.eclipse.jface.text.IDocument;
+import org.eclipse.jface.text.IRegion;
+import org.eclipse.jface.text.ITypedRegion;
+import org.eclipse.jface.text.presentation.IPresentationDamager;
+
+/**
+ * A simple presentation damager always damaging the whole partition.
+ * This is necessary if the partition contains multiline highlight regions.
+ *
+ * @since 4.0
+ */
+public class PartitionDamager implements IPresentationDamager {
+
+ /*
+ * @see org.eclipse.jface.text.presentation.IPresentationDamager#getDamageRegion(org.eclipse.jface.text.ITypedRegion, org.eclipse.jface.text.DocumentEvent, boolean)
+ */
+ public IRegion getDamageRegion(ITypedRegion partition, DocumentEvent event,
+ boolean documentPartitioningChanged) {
+ return partition;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.presentation.IPresentationDamager#setDocument(org.eclipse.jface.text.IDocument)
+ */
+ public void setDocument(IDocument document) {
+ }
+
+}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PreprocessorRule.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PreprocessorRule.java
index 0805c04a5d9..e6e66eb87cb 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PreprocessorRule.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/PreprocessorRule.java
@@ -7,15 +7,15 @@
*
* Contributors:
* QNX Software Systems - Initial API and implementation
+ * Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text;
import org.eclipse.jface.text.rules.ICharacterScanner;
-import org.eclipse.jface.text.rules.IWordDetector;
-import org.eclipse.jface.text.rules.WordRule;
-import org.eclipse.jface.text.rules.IRule;
import org.eclipse.jface.text.rules.IToken;
+import org.eclipse.jface.text.rules.IWordDetector;
import org.eclipse.jface.text.rules.Token;
+import org.eclipse.jface.text.rules.WordRule;
/**
* Implementation of IRule
for C/C++ preprocessor scanning.
@@ -23,9 +23,10 @@ import org.eclipse.jface.text.rules.Token;
* at the beginning of the string, then '#' sign, then 0 or more whitespaces
* again, and then directive itself.
*/
-public class PreprocessorRule extends WordRule implements IRule {
+public class PreprocessorRule extends WordRule {
private StringBuffer fBuffer = new StringBuffer();
+ private IToken fMalformedToken;
/**
* Creates a rule which, with the help of a word detector, will return the token
@@ -56,6 +57,33 @@ public class PreprocessorRule extends WordRule implements IRule {
super(detector, defaultToken);
}
+ /**
+ * Creates a rule which, with the help of an word detector, will return the token
+ * associated with the detected word. If no token has been associated, the
+ * specified default token will be returned.
+ *
+ * @param detector the word detector to be used by this rule, may not be null
+ * @param defaultToken the default token to be returned on success
+ * if nothing else is specified, may not be null
+ * @param malformedToken the token to be returned if the directive is malformed
+ *
+ * @see WordRule#addWord
+ */
+ public PreprocessorRule(IWordDetector detector, IToken defaultToken, IToken malformedToken) {
+ super(detector, defaultToken);
+ fMalformedToken= malformedToken;
+ }
+
+ /*
+ * @see org.eclipse.jface.text.rules.WordRule#addWord(java.lang.String, org.eclipse.jface.text.rules.IToken)
+ */
+ public void addWord(String word, IToken token) {
+ if (word.charAt(0) == '#') {
+ word= word.substring(1);
+ }
+ super.addWord(word, token);
+ }
+
/*
* @see IRule#evaluate
*/
@@ -64,14 +92,10 @@ public class PreprocessorRule extends WordRule implements IRule {
int nCharsToRollback = 0;
boolean hashSignDetected = false;
- if (scanner.getColumn() > 0)
- return Token.UNDEFINED;
-
do {
c = scanner.read();
nCharsToRollback++;
- } while (Character.isWhitespace((char) c));
-
+ } while (c == ' ' || c == '\t');
// Di- and trigraph support
if (c == '#') {
@@ -98,20 +122,29 @@ public class PreprocessorRule extends WordRule implements IRule {
do {
c = scanner.read();
- } while (Character.isWhitespace((char) c));
+ } while (c == ' ' || c == '\t');
fBuffer.setLength(0);
-
- do {
- fBuffer.append((char) c);
- c = scanner.read();
- } while (Character.isJavaIdentifierPart((char) c));
-
- scanner.unread();
-
- IToken token = (IToken) fWords.get("#" + fBuffer.toString()); //$NON-NLS-1$
+
+ if (c != '#') {
+ if (fDetector.isWordStart((char) c)) {
+ do {
+ fBuffer.append((char) c);
+ c = scanner.read();
+ } while (fDetector.isWordPart((char) c));
+ }
+ scanner.unread();
+ }
+ IToken token = (IToken) fWords.get(fBuffer.toString());
if (token != null)
return token;
+
+ if (fMalformedToken != null) {
+ do {
+ c = scanner.read();
+ } while (c != ICharacterScanner.EOF);
+ return fMalformedToken;
+ }
return fDefaultToken;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/util/CWhitespaceDetector.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/util/CWhitespaceDetector.java
index 1fb2534d0ef..e5f70f29a3a 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/util/CWhitespaceDetector.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/util/CWhitespaceDetector.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000 2005 IBM Corporation and others.
+ * Copyright (c) 2000, 2006 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
@@ -8,6 +8,7 @@
* Contributors:
* IBM Corporation - initial API and implementation
* QNX Software System
+ * Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.ui.text.util;
@@ -15,14 +16,22 @@ import org.eclipse.jface.text.rules.IWhitespaceDetector;
/**
- * A C aware white space detector.
+ * A simple white space detector.
*/
public class CWhitespaceDetector implements IWhitespaceDetector {
- /**
- * @see IWhitespaceDetector#isWhitespace
+ /*
+ * @see IWhitespaceDetector#isWhitespace(char)
*/
public boolean isWhitespace(char c) {
- return Character.isWhitespace(c);
+ switch (c) {
+ case ' ':
+ case '\t':
+ case '\r':
+ case '\n':
+ return true;
+ default:
+ return Character.isWhitespace(c);
+ }
}
}
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java
index cba76ad143e..cb9cb590126 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/PreferenceConstants.java
@@ -163,7 +163,106 @@ public class PreferenceConstants {
* @since 4.0
*/
public final static String EDITOR_C_KEYWORD_ITALIC= ICColorConstants.C_KEYWORD + EDITOR_ITALIC_SUFFIX;
+
+ /**
+ * A named preference that holds the color used to render preprocessor directives.
+ *
+ * Value is of type String
. A RGB color value encoded as a string
+ * using class PreferenceConverter
+ *
+ * Value is of type Boolean
.
+ *
+ * Value is of type Boolean
.
+ *
+ * Value is of type String
. A RGB color value encoded as a string
+ * using class PreferenceConverter
+ *
+ * Value is of type Boolean
.
+ *
+ * Value is of type Boolean
.
+ *
+ * Value is of type String
. A RGB color value encoded as a string
+ * using class PreferenceConverter
+ *
+ * Value is of type Boolean
.
+ *
+ * Value is of type Boolean
.
+ *
@@ -296,39 +395,6 @@ public class PreferenceConstants { */ public final static String EDITOR_C_NUMBER_ITALIC= ICColorConstants.C_NUMBER + EDITOR_ITALIC_SUFFIX; - /** - * A named preference that holds the color used to render headers. - *
- * Value is of type String
. A RGB color value encoded as a string
- * using class PreferenceConverter
- *
- * Value is of type Boolean
.
- *
- * Value is of type Boolean
.
- *
@@ -956,9 +1022,17 @@ public class PreferenceConstants { store.setDefault(EDITOR_C_NUMBER_BOLD, false); store.setDefault(EDITOR_C_NUMBER_ITALIC, false); - PreferenceConverter.setDefault(store, EDITOR_C_HEADER_COLOR, new RGB(42, 0, 255)); - store.setDefault(EDITOR_C_HEADER_BOLD, false); - store.setDefault(EDITOR_C_HEADER_ITALIC, false); + PreferenceConverter.setDefault(store, EDITOR_PP_DIRECTIVE_COLOR, new RGB(127, 0, 85)); + store.setDefault(EDITOR_PP_DIRECTIVE_BOLD, true); + store.setDefault(EDITOR_PP_DIRECTIVE_ITALIC, false); + + PreferenceConverter.setDefault(store, EDITOR_PP_HEADER_COLOR, new RGB(42, 0, 255)); + store.setDefault(EDITOR_PP_HEADER_BOLD, false); + store.setDefault(EDITOR_PP_HEADER_ITALIC, false); + + PreferenceConverter.setDefault(store, EDITOR_PP_DEFAULT_COLOR, new RGB(0, 0, 0)); + store.setDefault(EDITOR_PP_DEFAULT_BOLD, false); + store.setDefault(EDITOR_PP_DEFAULT_ITALIC, false); // folding store.setDefault(PreferenceConstants.EDITOR_FOLDING_ENABLED, false); diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ICPartitions.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ICPartitions.java index 861eba0df48..396bd1933be 100644 --- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ICPartitions.java +++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/ui/text/ICPartitions.java @@ -41,4 +41,9 @@ public interface ICPartitions { * The identifier of the C character partition content type. */ String C_CHARACTER= "__c_character"; //$NON-NLS-1$ + + /** + * The identifier of the C preprocessor partition content type. + */ + String C_PREPROCESSOR= "__c_preprocessor"; //$NON-NLS-1$ }