1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Dynamic macros and whitespace in macro-explorer, bug 23540.

This commit is contained in:
Markus Schorn 2008-01-17 16:02:44 +00:00
parent 13bad2303e
commit 2bf1905d6c
14 changed files with 300 additions and 158 deletions

View file

@ -45,6 +45,8 @@ public class ExpansionExplorerTests extends BaseTestCase {
}
final MacroExpander expander= createExpander(input[0]);
final String original= input[1];
verifyStepCount(expander, original, steps);
verifyStep(expander, original, Integer.MAX_VALUE, original, input[steps+1]);
for (i= 0; i < steps; i++) {
@ -52,18 +54,24 @@ public class ExpansionExplorerTests extends BaseTestCase {
}
}
private void verifyStepCount(MacroExpander expander, String original, int steps) {
MacroExpansionTracker tracker= new MacroExpansionTracker(Integer.MAX_VALUE);
expander.expand(original, tracker, "", 1);
assertEquals(steps, tracker.getStepCount());
}
private void verifyStep(MacroExpander expander, String original, int step, String expectedPre,
String expectedPost) {
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
expander.expand(original, tracker);
expander.expand(original, tracker, "", 1);
String pre = tracker.getCodeBeforeStep();
ReplaceEdit replacement = tracker.getReplacement();
assertNotNull(pre);
assertNotNull(replacement);
String post= apply(pre, replacement);
assertEquals(expectedPre, pre);
assertEquals(expectedPost, post);
assertEquals("incorrect value pre " + step, expectedPre, pre);
assertEquals("incorrect value post " + step, expectedPost, post);
}
private String apply(String pre, ReplaceEdit replacement) {
@ -91,7 +99,7 @@ public class ExpansionExplorerTests extends BaseTestCase {
// B
public void testNoOp() throws Exception {
performTest(1);
performTest(0);
}
// #define A B
@ -208,6 +216,69 @@ public class ExpansionExplorerTests extends BaseTestCase {
performTest(7);
}
// #define id(x) x
// id(
// id(a))
// id(
// a)
// a
public void testNewline() throws Exception {
performTest(2);
}
// #define f x _a _b x
// #define _a a
// #define _b b
// f
// x _a _b x
// x a _b x
// x a b x
public void testSpace() throws Exception {
performTest(3);
}
// #define L __LINE__
// #define x(a) a
// x(L)
// x(__LINE__)
// x(1)
// 1
public void testLineNumber() throws Exception {
performTest(3);
}
// #define L __LINE__
// #define x(a,b) a,b
// x(L,
// L)
// x(__LINE__,
// L)
// x(2,
// L)
// x(2,
// __LINE__)
// x(2,
// 2)
// 2,2
public void testLineNumber2() throws Exception {
performTest(5);
}
}

View file

@ -639,6 +639,19 @@ public class PreprocessorTests extends PreprocessorTestsBase {
validateProblemCount(0);
}
// #define A(x,y,z) x + y + z
// #define _t t
// A ( _t , , _t )
public void testEmptyToken() throws Exception {
initializeScanner();
validateIdentifier("t");
validateToken(IToken.tPLUS);
validateToken(IToken.tPLUS);
validateIdentifier("t");
}
// #define FOO 5
// # define BAR 10
// int x = FOO + BAR;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others.
* Copyright (c) 2004, 2008 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
@ -41,9 +41,7 @@ public interface IASTPreprocessorMacroDefinition extends
public void setName(IASTName name);
/**
* Get the macro expansion.
*
* @return String
* Returns the macro expansion, or an empty string for dynamic style macros.
*/
public String getExpansion();

View file

@ -1,12 +1,13 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* Copyright (c) 2004, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@ -29,7 +30,7 @@ public interface IMacroBinding extends IBinding {
char[][] getParameterList();
/**
* Returns the expansion of this macro definition.
* Returns the expansion of this macro definition, or <code>null</code> for dynamic-style macros.
* @since 5.0
*/
char[] getExpansion();
@ -44,7 +45,7 @@ public interface IMacroBinding extends IBinding {
char[][] getParameterPlaceholderList();
/**
* Returns the image of the expansion (also containing comments).
* Returns the image of the expansion (also containing comments), or <code>null</code> for dynamic style macros.
* @since 5.0
*/
char[] getExpansionImage();

View file

@ -230,7 +230,7 @@ class ASTInclusionStatement extends ASTPreprocessorNode implements IASTPreproces
}
}
class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
class ASTMacroDefinition extends ASTPreprocessorNode implements IASTPreprocessorObjectStyleMacroDefinition {
private final ASTPreprocessorName fName;
private final int fExpansionNumber;
private final int fExpansionOffset;
@ -238,7 +238,7 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
/**
* Regular constructor.
*/
public ASTObjectStyleMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro,
public ASTMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro,
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
fExpansionNumber= expansionNumber;
@ -250,7 +250,7 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
* Constructor for built-in macros
* @param expansionOffset
*/
public ASTObjectStyleMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro, IASTFileLocation floc, int expansionOffset) {
public ASTMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro, IASTFileLocation floc, int expansionOffset) {
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, -1, -1);
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, floc, macro.getNameCharArray(), macro);
fExpansionNumber= -1;
@ -270,7 +270,12 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
}
public String getExpansion() {
return new String(getMacro().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);
}
public IASTName getName() {
@ -306,7 +311,10 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
if (fExpansionOffset >= 0) {
String fileName= fName.getContainingFilename();
if (fileName != null) {
return new ASTFileLocationForBuiltins(fileName, fExpansionOffset, getMacro().getExpansionImage().length);
final char[] expansionImage = getMacro().getExpansionImage();
if (expansionImage != null) {
return new ASTFileLocationForBuiltins(fileName, fExpansionOffset, expansionImage.length);
}
}
}
return null;
@ -328,7 +336,7 @@ class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyle
public void setParameter(String value) {assert false;}
}
class ASTFunctionStyleMacroDefinition extends ASTObjectStyleMacroDefinition implements IASTPreprocessorFunctionStyleMacroDefinition {
class ASTFunctionStyleMacroDefinition extends ASTMacroDefinition implements IASTPreprocessorFunctionStyleMacroDefinition {
/**
* Regular constructor.
*/

View file

@ -14,8 +14,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
import java.io.File;
import java.io.IOException;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -66,8 +64,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
public static final int tNOSPACE= IToken.FIRST_RESERVED_PREPROCESSOR+4;
public static final int tMACRO_PARAMETER= IToken.FIRST_RESERVED_PREPROCESSOR+5;
private static final int ORIGIN_PREPROCESSOR_DIRECTIVE = OffsetLimitReachedException.ORIGIN_PREPROCESSOR_DIRECTIVE;
private static final int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE;
// private static final int ORIGIN_MACRO_EXPANSION = OffsetLimitReachedException.ORIGIN_MACRO_EXPANSION;
@ -83,6 +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 interface IIncludeFileTester {
Object checkFile(String path, String fileName);
@ -104,63 +104,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
}
};
// standard built-ins
final private DynamicStyleMacro __FILE__= new DynamicStyleMacro("__FILE__".toCharArray()) { //$NON-NLS-1$
public Token execute() {
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
buffer.append(getCurrentFilename());
buffer.append('\"');
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
}
};
final private DynamicStyleMacro __DATE__= new DynamicStyleMacro("__DATE__".toCharArray()) { //$NON-NLS-1$
final private void append(StringBuffer buffer, int value) {
if (value < 10)
buffer.append("0"); //$NON-NLS-1$
buffer.append(value);
}
public Token execute() {
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
DateFormatSymbols dfs= new DateFormatSymbols();
buffer.append(dfs.getShortMonths()[cal.get(Calendar.MONTH)]);
buffer.append(" "); //$NON-NLS-1$
append(buffer, cal.get(Calendar.DAY_OF_MONTH));
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());
}
};
final private DynamicStyleMacro __TIME__ = new DynamicStyleMacro("__TIME__".toCharArray()) { //$NON-NLS-1$
final private void append(StringBuffer buffer, int value) {
if (value < 10)
buffer.append("0"); //$NON-NLS-1$
buffer.append(value);
}
public Token execute() {
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
append(buffer, cal.get(Calendar.HOUR_OF_DAY));
buffer.append(":"); //$NON-NLS-1$
append(buffer, cal.get(Calendar.MINUTE));
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());
}
};
final private DynamicStyleMacro __LINE__ = new DynamicStyleMacro("__LINE__".toCharArray()) { //$NON-NLS-1$
public Token execute() {
int lineNumber= fLocationMap.getCurrentLineNumber(fCurrentContext.currentLexerToken().getOffset());
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
}
};
final private IParserLogService fLog;
final private IIndexBasedCodeReaderFactory fCodeReaderFactory;
private final ExpressionEvaluator fExpressionEvaluator;

View file

@ -48,7 +48,7 @@ public class LocationMap implements ILocationResolver {
private ArrayList<ASTPreprocessorNode> fDirectives= new ArrayList<ASTPreprocessorNode>();
private ArrayList<ASTProblem> fProblems= new ArrayList<ASTProblem>();
private ArrayList<ASTComment> fComments= new ArrayList<ASTComment>();
private ArrayList<ASTObjectStyleMacroDefinition> fBuiltinMacros= new ArrayList<ASTObjectStyleMacroDefinition>();
private ArrayList<ASTMacroDefinition> fBuiltinMacros= new ArrayList<ASTMacroDefinition>();
private ArrayList<IASTName> fMacroReferences= new ArrayList<IASTName>();
private LocationCtxFile fRootContext= null;
@ -69,12 +69,12 @@ public class LocationMap implements ILocationResolver {
}
private void registerPredefinedMacro(IMacroBinding macro, IASTFileLocation nameloc, int expansionOffset) {
ASTObjectStyleMacroDefinition astmacro;
ASTMacroDefinition astmacro;
if (macro.isFunctionStyle()) {
astmacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
}
else {
astmacro= new ASTObjectStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
astmacro= new ASTMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
}
fBuiltinMacros.add(astmacro);
}
@ -291,7 +291,7 @@ public class LocationMap implements ILocationResolver {
endOffset= getSequenceNumberForOffset(endOffset);
ASTPreprocessorNode astMacro;
if (!macrodef.isFunctionStyle()) {
astMacro= new ASTObjectStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
astMacro= new ASTMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
}
else {
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);

View file

@ -136,6 +136,11 @@ public class MacroExpander {
private int fStartOffset;
private int fEndOffset;
// for using the expander to track expansions
private String fFixedCurrentFilename;
private int fFixedLineNumber;
private char[] fFixedInput;
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap locationMap, LexerOptions lexOptions) {
fDictionary= macroDictionary;
fLocationMap= locationMap;
@ -173,10 +178,13 @@ public class MacroExpander {
* Method for tracking macro expansions.
* @since 5.0
*/
public void expand(String beforeExpansion, MacroExpansionTracker tracker) {
Lexer lexer= new Lexer(beforeExpansion.toCharArray(), fLexOptions, fLog, this);
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath, int lineNumber) {
fImplicitMacroExpansions.clear();
fImageLocationInfos.clear();
fFixedInput= beforeExpansion.toCharArray();
fFixedCurrentFilename= filePath;
fFixedLineNumber= lineNumber;
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
try {
tracker.start(lexer);
@ -362,17 +370,28 @@ public class MacroExpander {
return null;
}
private void addSpacemarker(Token l, Token t, TokenList target) {
private static boolean isNeighborInSource(Token l, Token t) {
if (l != null && t != null) {
final Object s1= l.fSource;
final Object s2= t.fSource;
if (s1 == s2 && s1 != null && l.getType() != CPreprocessor.tSPACE) {
if (l.getEndOffset() == t.getOffset()) {
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
}
else {
target.append(new Token(CPreprocessor.tSPACE, s1, l.getEndOffset(), t.getOffset()));
}
return s1 == s2 && s1 != null &&
l.getType() != CPreprocessor.tSPACE && t.getType() != CPreprocessor.tSPACE;
}
return false;
}
static boolean hasImplicitSpace(Token l, Token t) {
return isNeighborInSource(l, t) && l.getEndOffset() != t.getOffset();
}
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()));
}
}
}
@ -397,7 +416,7 @@ public class MacroExpander {
boolean complete= false;
boolean isFirstOfArg= true;
Token lastToken= null;
Token spaceMarker= null;
TokenList spaceMarkers= new TokenList();
loop: while (true) {
Token t= input.fetchFirst();
if (t == null) {
@ -408,6 +427,7 @@ public class MacroExpander {
case IToken.tEND_OF_INPUT:
case IToken.tCOMPLETION:
case CPreprocessor.tSCOPE_MARKER:
case Lexer.tNEWLINE:
break;
default:
tracker.addFunctionStyleMacroExpansionToken((Token) t.clone());
@ -449,7 +469,7 @@ public class MacroExpander {
if (nesting == 0) {
if (idx < argCount-1) { // next argument
isFirstOfArg= true;
spaceMarker= null;
spaceMarkers.clear();
idx++;
continue loop;
}
@ -471,7 +491,7 @@ public class MacroExpander {
case CPreprocessor.tSPACE:
case CPreprocessor.tNOSPACE:
if (!isFirstOfArg) {
spaceMarker= t;
spaceMarkers.append(t);
}
continue loop;
@ -481,10 +501,7 @@ public class MacroExpander {
if (argCount == 0) {
break loop;
}
if (spaceMarker != null) {
result[idx].append(spaceMarker);
spaceMarker= null;
}
result[idx].appendAll(spaceMarkers);
result[idx].append(t);
isFirstOfArg= false;
}
@ -500,7 +517,7 @@ public class MacroExpander {
}
private void replaceArgs(PreprocessorMacro macro, TokenList[] args, TokenList[] expandedArgs, TokenList result) {
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions));
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
Token l= null;
Token n;
@ -638,7 +655,7 @@ public class MacroExpander {
private BitSet getParamUsage(PreprocessorMacro macro) {
final BitSet result= new BitSet();
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions);
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions, this);
Token l= null;
Token n;
@ -684,7 +701,7 @@ public class MacroExpander {
}
private void objStyleTokenPaste(PreprocessorMacro macro, TokenList result) {
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions));
TokenList replacement= clone(macro.getTokens(fDefinitionParser, fLexOptions, this));
Token l= null;
Token n;
@ -862,9 +879,33 @@ public class MacroExpander {
}
}
static boolean hasImplicitSpace(Token l, Token t) {
return l != null &&
l.fSource != null && l.fSource == t.fSource &&
l.getEndOffset() != t.getOffset() && t.getType() != CPreprocessor.tSPACE;
int getCurrentLineNumber() {
if (fFixedInput != null) {
return fFixedLineNumber + countNewlines(fFixedInput);
}
if (fLocationMap != null) {
return fLocationMap.getCurrentLineNumber(fEndOffset);
}
return 0;
}
private int countNewlines(char[] input) {
int nl= 0;
for (int i = 0; i < input.length && i<fEndOffset; i++) {
if (input[i] == '\n') {
nl++;
}
}
return nl;
}
String getCurrentFilename() {
if (fFixedCurrentFilename != null) {
return fFixedCurrentFilename;
}
if (fLocationMap != null) {
return fLocationMap.getCurrentFilePath();
}
return ""; //$NON-NLS-1$
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2007 Wind River Systems, Inc. and others.
* Copyright (c) 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
@ -252,7 +252,9 @@ public class MacroExpansionTracker {
TokenList p = minfo.fArguments.get(pcount);
if (p != null) {
active = false;
addSpacemarker(t, n, result);
if (n != null && n.getType() != IToken.tCOMMA && n.getType() != IToken.tRPAREN) {
MacroExpander.addSpacemarker(t, n, result);
}
result.appendAll(p);
}
}
@ -261,7 +263,7 @@ public class MacroExpansionTracker {
case IToken.tRPAREN:
if (!active && nesting == 0) {
addSpacemarker(l, t, result);
MacroExpander.addSpacemarker(l, t, result);
active= true;
}
if (active) {
@ -276,13 +278,15 @@ public class MacroExpansionTracker {
if (nesting == 0) {
if (++pcount < minfo.fArguments.size()) {
if (!active) {
addSpacemarker(l, t, result);
MacroExpander.addSpacemarker(l, t, result);
}
result.append(t);
TokenList p = minfo.fArguments.get(pcount);
active = p == null;
if (!active) {
addSpacemarker(t, n, result);
if (n != null && n.getType() != IToken.tCOMMA && n.getType() != IToken.tRPAREN) {
MacroExpander.addSpacemarker(t, n, result);
}
result.appendAll(p);
}
}
@ -299,22 +303,6 @@ public class MacroExpansionTracker {
}
}
private void addSpacemarker(Token l, Token t, TokenList target) {
Token tl= target.last();
if (tl != null && tl.getType() == CPreprocessor.tSPACE) {
return;
}
if (l != null && t != null) {
final Object s1= l.fSource;
final Object s2= t.fSource;
if (s1 == s2 && s1 != null && l.getType() != CPreprocessor.tSPACE) {
if (l.getEndOffset() != t.getOffset()) {
target.append(new Token(CPreprocessor.tSPACE, s1, l.getEndOffset(), t.getOffset()));
}
}
}
}
/**
* Informs the tracker that the function style macro has been expanded.
*/

View file

@ -49,6 +49,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
private final char[] fSource;
private final int[] fBoundaries;
private final SingleMacroExpansionExplorer[] fDelegates;
private String fFilePath;
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
if (tu == null || loc == null || loc.getNodeLength() == 0) {
@ -75,6 +76,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
}
}
fFilePath= tu.getFilePath();
fSource= resolver.getUnpreprocessedSignature(loc);
fBoundaries= new int[count*2+1];
fDelegates= new SingleMacroExpansionExplorer[count];
@ -91,7 +93,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
fBoundaries[++bidx]= from;
fBoundaries[++bidx]= to;
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from), ref,
resolver.getImplicitMacroReferences(ref));
resolver.getImplicitMacroReferences(ref), fFilePath, refLoc.getStartingLineNumber());
}
}
fBoundaries[++bidx]= fSource.length;

View file

@ -10,9 +10,13 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.parser.scanner;
import java.text.DateFormatSymbols;
import java.util.Calendar;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.parser.IToken;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
import org.eclipse.cdt.internal.core.dom.Linkage;
@ -83,27 +87,7 @@ abstract class PreprocessorMacro implements IMacroBinding {
buf.append(')');
return buf.toString();
}
public abstract TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions);
}
abstract class DynamicStyleMacro extends PreprocessorMacro {
public DynamicStyleMacro(char[] name) {
super(name);
}
public char[] getExpansion() {
return getExpansionImage();
}
public char[] getExpansionImage() {
return execute().getCharImage();
}
public abstract Token execute();
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions) {
TokenList result= new TokenList();
result.append(execute());
return result;
}
public abstract TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions, MacroExpander expander);
}
class ObjectStyleMacro extends PreprocessorMacro {
@ -158,7 +142,7 @@ class ObjectStyleMacro extends PreprocessorMacro {
return result;
}
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions) {
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions, MacroExpander expander) {
if (fExpansionTokens == null) {
fExpansionTokens= new TokenList();
Lexer lex= new Lexer(fExpansion, fExpansionOffset, fEndOffset, lexOptions, ILexerLog.NULL, this);
@ -267,3 +251,90 @@ class FunctionStyleMacro extends ObjectStyleMacro {
return true;
}
}
abstract class DynamicStyleMacro extends PreprocessorMacro {
public DynamicStyleMacro(char[] name) {
super(name);
}
public char[] getExpansion() {
return null;
}
public char[] getExpansionImage() {
return null;
}
public abstract Token execute(MacroExpander expander);
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions, MacroExpander expander) {
TokenList result= new TokenList();
result.append(execute(expander));
return result;
}
final protected void append(StringBuffer buffer, int value) {
if (value < 10)
buffer.append("0"); //$NON-NLS-1$
buffer.append(value);
}
}
final class DateMacro extends DynamicStyleMacro {
DateMacro(char[] name) {
super(name);
}
public Token execute(MacroExpander expander) {
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
DateFormatSymbols dfs= new DateFormatSymbols();
buffer.append(dfs.getShortMonths()[cal.get(Calendar.MONTH)]);
buffer.append(" "); //$NON-NLS-1$
append(buffer, cal.get(Calendar.DAY_OF_MONTH));
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());
}
}
final class FileMacro extends DynamicStyleMacro {
FileMacro(char[] name) {
super(name);
}
public Token execute(MacroExpander expander) {
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
buffer.append(expander.getCurrentFilename());
buffer.append('\"');
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
}
}
final class LineMacro extends DynamicStyleMacro {
LineMacro(char[] name) {
super(name);
}
public Token execute(MacroExpander expander) {
int lineNumber= expander.getCurrentLineNumber();
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
}
}
final class TimeMacro extends DynamicStyleMacro {
TimeMacro(char[] name) {
super(name);
}
public Token execute(MacroExpander expander) {
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
Calendar cal = Calendar.getInstance();
append(buffer, cal.get(Calendar.HOUR_OF_DAY));
buffer.append(":"); //$NON-NLS-1$
append(buffer, cal.get(Calendar.MINUTE));
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());
}
}

View file

@ -32,15 +32,17 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
private final CharArrayMap<PreprocessorMacro> fDictionary;
private MacroExpansionStep fFullExpansion;
private int fExpansionCount;
private String fFilePath;
private int fLineNumber;
public SingleMacroExpansionExplorer(String input, IASTName ref, IASTName[] implicitRefs) {
public SingleMacroExpansionExplorer(String input, IASTName ref, IASTName[] implicitRefs, String filePath, int lineNumber) {
fInput= input;
fDictionary= createDictionary(ref, implicitRefs);
fFilePath= filePath;
fLineNumber= lineNumber;
}
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName ref, IASTName[] implicitRefs) {
// mstodo handle dynamic style macros
// mstodo clone index-macros
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(implicitRefs.length+1);
addMacroDefinition(map, ref);
for (IASTName name : implicitRefs) {
@ -71,7 +73,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
private void computeExpansion() {
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
MacroExpansionTracker tracker= new MacroExpansionTracker(Integer.MAX_VALUE);
expander.expand(fInput, tracker);
expander.expand(fInput, tracker, fFilePath, fLineNumber);
fExpansionCount= tracker.getStepCount();
ReplaceEdit r= tracker.getReplacement();
@ -87,7 +89,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
}
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
expander.expand(fInput, tracker);
expander.expand(fInput, tracker, fFilePath, fLineNumber);
fExpansionCount= tracker.getStepCount();
ReplaceEdit r= tracker.getReplacement();

View file

@ -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
@ -121,4 +121,8 @@ class TokenList {
fLast= l;
}
}
public void clear() {
fFirst= fLast= null;
}
}

View file

@ -173,7 +173,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
fExpansion= getExpansionInDB().getChars();
} catch (CoreException e) {
CCorePlugin.log(e);
fExpansion= new char[] { ' ' };
fExpansion= new char[] {};
}
}
return fExpansion;