diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/TestMacro.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/TestMacro.java
index ad256195b6a..42ebdec3021 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/TestMacro.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/scanner/TestMacro.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2007 Wind River Systems, Inc. and others.
+ * Copyright (c) 2007, 2008 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
@@ -73,4 +73,8 @@ final class TestMacro implements IMacroBinding {
public char[][] getParameterPlaceholderList() {
return getParameterList();
}
+
+ public boolean isDynamic() {
+ return false;
+ }
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java
index bdc15b5d10e..e06f574685a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IMacroBinding.java
@@ -24,13 +24,19 @@ public interface IMacroBinding extends IBinding {
*/
boolean isFunctionStyle();
+ /**
+ * Returns true
if this is a dynamic macro.
+ * @since 5.0
+ */
+ boolean isDynamic();
+
/**
* Returns the parameter names or null
if this is not a function style macro.
*/
char[][] getParameterList();
/**
- * Returns the expansion of this macro definition, or null
for dynamic-style macros.
+ * Returns the expansion of this macro definition. For dynamic macros an exemplary image is returned.
* @since 5.0
*/
char[] getExpansion();
@@ -45,7 +51,7 @@ public interface IMacroBinding extends IBinding {
char[][] getParameterPlaceholderList();
/**
- * Returns the image of the expansion (also containing comments), or null
for dynamic style macros.
+ * Returns the image of the expansion (also containing comments). For dynamic macros an exemplary image is returned.
* @since 5.0
*/
char[] getExpansionImage();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
index b0187448c3a..e9c6ac642bd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorNode.java
@@ -270,12 +270,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
}
public String getExpansion() {
- final char[] expansion = getMacro().getExpansion();
- // for dynamic style macros return an empty string
- if (expansion == null) {
- return ""; //$NON-NLS-1$
- }
- return new String(expansion);
+ return new String(getMacro().getExpansion());
}
public IASTName getName() {
@@ -312,9 +307,7 @@ class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessor
String fileName= fName.getContainingFilename();
if (fileName != null) {
final char[] expansionImage = getMacro().getExpansionImage();
- if (expansionImage != null) {
- return new ASTFileLocationForBuiltins(fileName, fExpansionOffset, expansionImage.length);
- }
+ return new ASTFileLocationForBuiltins(fileName, fExpansionOffset, expansionImage.length);
}
}
return null;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java
index 85c9ab6d0f6..0c3d616d0ef 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/CPreprocessor.java
@@ -79,10 +79,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
private static final ObjectStyleMacro __STDC_HOSTED__ = new ObjectStyleMacro("__STDC_HOSTED_".toCharArray(), ONE); //$NON-NLS-1$
private static final ObjectStyleMacro __STDC_VERSION__ = new ObjectStyleMacro("__STDC_VERSION_".toCharArray(), "199901L".toCharArray()); //$NON-NLS-1$ //$NON-NLS-2$
- private static final DynamicStyleMacro __FILE__= new FileMacro("__FILE__".toCharArray()); //$NON-NLS-1$
- private static final DynamicStyleMacro __DATE__= new DateMacro("__DATE__".toCharArray()); //$NON-NLS-1$
- private static final DynamicStyleMacro __TIME__ = new TimeMacro("__TIME__".toCharArray()); //$NON-NLS-1$
- private static final DynamicStyleMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
+ private static final DynamicMacro __FILE__= new FileMacro("__FILE__".toCharArray()); //$NON-NLS-1$
+ private static final DynamicMacro __DATE__= new DateMacro("__DATE__".toCharArray()); //$NON-NLS-1$
+ private static final DynamicMacro __TIME__ = new TimeMacro("__TIME__".toCharArray()); //$NON-NLS-1$
+ private static final DynamicMacro __LINE__ = new LineMacro("__LINE__".toCharArray()); //$NON-NLS-1$
private interface IIncludeFileTester {
Object checkFile(String path, String fileName);
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java
index bf2adc5b036..79482550ced 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java
@@ -165,7 +165,11 @@ public class MacroExpander {
// setup input sequence
TokenSource input= new TokenSource(lexer, stopAtNewline);
TokenList firstExpansion= new TokenList();
+
+ firstExpansion.append(new ExpansionBoundary(macro, true));
expandOne(identifier, macro, forbidden, input, firstExpansion, null);
+ firstExpansion.append(new ExpansionBoundary(macro, false));
+
input.prepend(firstExpansion);
TokenList result= expandAll(input, forbidden, null);
@@ -208,7 +212,10 @@ public class MacroExpander {
// setup input sequence
TokenSource input= new TokenSource(lexer, false);
TokenList firstExpansion= new TokenList();
+
+ firstExpansion.append(new ExpansionBoundary(macro, true));
expandOne(identifier, macro, forbidden, input, firstExpansion, tracker);
+ firstExpansion.append(new ExpansionBoundary(macro, false));
input.prepend(firstExpansion);
TokenList result= expandAll(input, forbidden, tracker);
@@ -227,7 +234,6 @@ public class MacroExpander {
IdentityHashMap forbidden, TokenSource input, TokenList result,
MacroExpansionTracker tracker)
throws OffsetLimitReachedException {
- result.append(new ExpansionBoundary(macro, true));
if (macro.isFunctionStyle()) {
final int paramCount = macro.getParameterPlaceholderList().length;
final TokenSource[] argInputs= new TokenSource[paramCount];
@@ -290,7 +296,6 @@ public class MacroExpander {
tracker.endObjectStyleMacro();
}
}
- result.append(new ExpansionBoundary(macro, false));
return lastConsumed;
}
@@ -313,8 +318,7 @@ public class MacroExpander {
switch(t.getType()) {
case CPreprocessor.tSCOPE_MARKER:
((ExpansionBoundary) t).execute(forbidden);
- t= input.removeFirst(); // don't change l
- continue;
+ break;
case IToken.tIDENTIFIER:
PreprocessorMacro macro= fDictionary.get(t.getCharImage());
if (tracker != null && tracker.isDone()) {
@@ -339,7 +343,9 @@ public class MacroExpander {
TokenList replacement= new TokenList();
addSpacemarker(l, t, replacement); // start expansion
+ replacement.append(new ExpansionBoundary(macro, true));
Token last= expandOne(t, macro, forbidden, input, replacement, tracker);
+ replacement.append(new ExpansionBoundary(macro, false));
addSpacemarker(last, input.first(), replacement); // end expansion
input.prepend(replacement);
@@ -371,14 +377,7 @@ public class MacroExpander {
}
private static boolean isNeighborInSource(Token l, Token t) {
- if (l != null && t != null) {
- final Object s1= l.fSource;
- final Object s2= t.fSource;
- return s1 == s2 && s1 != null &&
- l.getType() != CPreprocessor.tSPACE && t.getType() != CPreprocessor.tSPACE;
- }
- return false;
-
+ return l != null && t != null && l.fSource != null && l.fSource == t.fSource;
}
static boolean hasImplicitSpace(Token l, Token t) {
@@ -387,15 +386,15 @@ public class MacroExpander {
static void addSpacemarker(Token l, Token t, TokenList target) {
if (isNeighborInSource(l, t)) {
- if (l.getEndOffset() == t.getOffset()) {
- target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
- }
- else {
- target.append(new Token(CPreprocessor.tSPACE, l.fSource, l.getEndOffset(), t.getOffset()));
+ final int from= l.getEndOffset();
+ final int to= t.getOffset();
+ if (from != to) {
+ target.append(new Token(CPreprocessor.tSPACE, l.fSource, from, to));
}
}
+ target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
}
-
+
/**
* Expects that the identifier has been consumed.
* @param forbidden
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionTracker.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionTracker.java
index ab3ed5c4289..f3d93e07bbf 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionTracker.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpansionTracker.java
@@ -181,7 +181,10 @@ public class MacroExpansionTracker {
return rootInput;
}
if (source instanceof PreprocessorMacro) {
- return ((PreprocessorMacro) source).getExpansionImage();
+ final PreprocessorMacro pm = (PreprocessorMacro) source;
+ if (!pm.isDynamic()) {
+ return pm.getExpansionImage();
+ }
}
return null;
}
@@ -254,8 +257,8 @@ public class MacroExpansionTracker {
active = false;
if (n != null && n.getType() != IToken.tCOMMA && n.getType() != IToken.tRPAREN) {
MacroExpander.addSpacemarker(t, n, result);
+ result.appendAll(p);
}
- result.appendAll(p);
}
}
}
@@ -286,8 +289,8 @@ public class MacroExpansionTracker {
if (!active) {
if (n != null && n.getType() != IToken.tCOMMA && n.getType() != IToken.tRPAREN) {
MacroExpander.addSpacemarker(t, n, result);
+ result.appendAll(p);
}
- result.appendAll(p);
}
}
} else if (active) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java
index 1b3c77aad06..1d2dd5759d0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/PreprocessorMacro.java
@@ -153,6 +153,10 @@ class ObjectStyleMacro extends PreprocessorMacro {
}
return fExpansionTokens;
}
+
+ public final boolean isDynamic() {
+ return false;
+ }
}
@@ -252,16 +256,13 @@ class FunctionStyleMacro extends ObjectStyleMacro {
}
}
-abstract class DynamicStyleMacro extends PreprocessorMacro {
+abstract class DynamicMacro extends PreprocessorMacro {
- public DynamicStyleMacro(char[] name) {
+ public DynamicMacro(char[] name) {
super(name);
}
- public char[] getExpansion() {
- return null;
- }
- public char[] getExpansionImage() {
- return null;
+ public final char[] getExpansion() {
+ return getExpansionImage();
}
public abstract Token execute(MacroExpander expander);
@@ -271,20 +272,29 @@ abstract class DynamicStyleMacro extends PreprocessorMacro {
return result;
}
- final protected void append(StringBuffer buffer, int value) {
+ final protected void append(StringBuilder buffer, int value) {
if (value < 10)
buffer.append("0"); //$NON-NLS-1$
buffer.append(value);
}
+
+ public final boolean isDynamic() {
+ return true;
+ }
}
-final class DateMacro extends DynamicStyleMacro {
+final class DateMacro extends DynamicMacro {
DateMacro(char[] name) {
super(name);
}
public Token execute(MacroExpander expander) {
- StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
+ return new TokenWithImage(IToken.tSTRING, null, 0, 0, createDate());
+ }
+
+ private char[] createDate() {
+ char[] charArray;
+ StringBuilder buffer = new StringBuilder("\""); //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
DateFormatSymbols dfs= new DateFormatSymbols();
buffer.append(dfs.getShortMonths()[cal.get(Calendar.MONTH)]);
@@ -293,11 +303,16 @@ final class DateMacro extends DynamicStyleMacro {
buffer.append(" "); //$NON-NLS-1$
buffer.append(cal.get(Calendar.YEAR));
buffer.append("\""); //$NON-NLS-1$
- return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
- }
+ charArray = buffer.toString().toCharArray();
+ return charArray;
+ }
+
+ public char[] getExpansionImage() {
+ return createDate();
+ }
}
-final class FileMacro extends DynamicStyleMacro {
+final class FileMacro extends DynamicMacro {
FileMacro(char[] name) {
super(name);
}
@@ -308,9 +323,13 @@ final class FileMacro extends DynamicStyleMacro {
buffer.append('\"');
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
}
+
+ public char[] getExpansionImage() {
+ return "\"file\"".toCharArray(); //$NON-NLS-1$
+ }
}
-final class LineMacro extends DynamicStyleMacro {
+final class LineMacro extends DynamicMacro {
LineMacro(char[] name) {
super(name);
}
@@ -318,15 +337,22 @@ final class LineMacro extends DynamicStyleMacro {
int lineNumber= expander.getCurrentLineNumber();
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
}
+ public char[] getExpansionImage() {
+ return new char[] {'1'};
+ }
}
-final class TimeMacro extends DynamicStyleMacro {
+final class TimeMacro extends DynamicMacro {
TimeMacro(char[] name) {
super(name);
}
public Token execute(MacroExpander expander) {
- StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
+ return new TokenWithImage(IToken.tSTRING, null, 0, 0, createDate());
+ }
+
+ private char[] createDate() {
+ StringBuilder buffer = new StringBuilder("\""); //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
append(buffer, cal.get(Calendar.HOUR_OF_DAY));
buffer.append(":"); //$NON-NLS-1$
@@ -334,7 +360,11 @@ final class TimeMacro extends DynamicStyleMacro {
buffer.append(":"); //$NON-NLS-1$
append(buffer, cal.get(Calendar.SECOND));
buffer.append("\""); //$NON-NLS-1$
- return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
+ return buffer.toString().toCharArray();
}
+
+ public char[] getExpansionImage() {
+ return createDate();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenList.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenList.java
index 4d86f607b93..cbc020bdf26 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenList.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/TokenList.java
@@ -125,4 +125,8 @@ class TokenList {
public void clear() {
fFirst= fLast= null;
}
+
+ public boolean isEmpty() {
+ return fFirst==null;
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
index 7ac2af8fc26..e3891ca6cb0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMMacro.java
@@ -276,6 +276,10 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
public boolean isFunctionStyle() {
return getParameterList() != null;
}
+
+ public boolean isDynamic() {
+ return false;
+ }
public ILinkage getLinkage() throws CoreException {
return Linkage.NO_LINKAGE;
diff --git a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CMacroExpansionExplorationControl.java b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CMacroExpansionExplorationControl.java
index c8226472914..59273b99963 100644
--- a/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CMacroExpansionExplorationControl.java
+++ b/core/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/text/c/hover/CMacroExpansionExplorationControl.java
@@ -351,9 +351,8 @@ public class CMacroExpansionExplorationControl extends AbstractCompareViewerInfo
buffer.append(')');
}
buffer.append(' ');
- final char[] expansionImage = binding.getExpansionImage();
- if (expansionImage != null) {
- buffer.append(expansionImage);
+ if (!binding.isDynamic()) {
+ buffer.append(binding.getExpansionImage());
}
else {
ReplaceEdit[] replacements= expansionStep.getReplacements();