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:
parent
13bad2303e
commit
2bf1905d6c
14 changed files with 300 additions and 158 deletions
|
@ -46,24 +46,32 @@ public class ExpansionExplorerTests extends BaseTestCase {
|
||||||
final MacroExpander expander= createExpander(input[0]);
|
final MacroExpander expander= createExpander(input[0]);
|
||||||
final String original= input[1];
|
final String original= input[1];
|
||||||
|
|
||||||
|
verifyStepCount(expander, original, steps);
|
||||||
|
|
||||||
verifyStep(expander, original, Integer.MAX_VALUE, original, input[steps+1]);
|
verifyStep(expander, original, Integer.MAX_VALUE, original, input[steps+1]);
|
||||||
for (i= 0; i < steps; i++) {
|
for (i= 0; i < steps; i++) {
|
||||||
verifyStep(expander, original, i, input[i+1], input[i+2]);
|
verifyStep(expander, original, i, input[i+1], input[i+2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
private void verifyStep(MacroExpander expander, String original, int step, String expectedPre,
|
||||||
String expectedPost) {
|
String expectedPost) {
|
||||||
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
|
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
|
||||||
expander.expand(original, tracker);
|
expander.expand(original, tracker, "", 1);
|
||||||
String pre = tracker.getCodeBeforeStep();
|
String pre = tracker.getCodeBeforeStep();
|
||||||
ReplaceEdit replacement = tracker.getReplacement();
|
ReplaceEdit replacement = tracker.getReplacement();
|
||||||
assertNotNull(pre);
|
assertNotNull(pre);
|
||||||
assertNotNull(replacement);
|
assertNotNull(replacement);
|
||||||
String post= apply(pre, replacement);
|
String post= apply(pre, replacement);
|
||||||
|
|
||||||
assertEquals(expectedPre, pre);
|
assertEquals("incorrect value pre " + step, expectedPre, pre);
|
||||||
assertEquals(expectedPost, post);
|
assertEquals("incorrect value post " + step, expectedPost, post);
|
||||||
}
|
}
|
||||||
|
|
||||||
private String apply(String pre, ReplaceEdit replacement) {
|
private String apply(String pre, ReplaceEdit replacement) {
|
||||||
|
@ -91,7 +99,7 @@ public class ExpansionExplorerTests extends BaseTestCase {
|
||||||
|
|
||||||
// B
|
// B
|
||||||
public void testNoOp() throws Exception {
|
public void testNoOp() throws Exception {
|
||||||
performTest(1);
|
performTest(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// #define A B
|
// #define A B
|
||||||
|
@ -208,6 +216,69 @@ public class ExpansionExplorerTests extends BaseTestCase {
|
||||||
performTest(7);
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -639,6 +639,19 @@ public class PreprocessorTests extends PreprocessorTestsBase {
|
||||||
validateProblemCount(0);
|
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 FOO 5
|
||||||
// # define BAR 10
|
// # define BAR 10
|
||||||
// int x = FOO + BAR;
|
// int x = FOO + BAR;
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -41,9 +41,7 @@ public interface IASTPreprocessorMacroDefinition extends
|
||||||
public void setName(IASTName name);
|
public void setName(IASTName name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the macro expansion.
|
* Returns the macro expansion, or an empty string for dynamic style macros.
|
||||||
*
|
|
||||||
* @return String
|
|
||||||
*/
|
*/
|
||||||
public String getExpansion();
|
public String getExpansion();
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* 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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -7,6 +7,7 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM - Initial API and implementation
|
* IBM - Initial API and implementation
|
||||||
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast;
|
package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
|
@ -29,7 +30,7 @@ public interface IMacroBinding extends IBinding {
|
||||||
char[][] getParameterList();
|
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
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
char[] getExpansion();
|
char[] getExpansion();
|
||||||
|
@ -44,7 +45,7 @@ public interface IMacroBinding extends IBinding {
|
||||||
char[][] getParameterPlaceholderList();
|
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
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
char[] getExpansionImage();
|
char[] getExpansionImage();
|
||||||
|
|
|
@ -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 ASTPreprocessorName fName;
|
||||||
private final int fExpansionNumber;
|
private final int fExpansionNumber;
|
||||||
private final int fExpansionOffset;
|
private final int fExpansionOffset;
|
||||||
|
@ -238,7 +238,7 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
|
||||||
/**
|
/**
|
||||||
* Regular constructor.
|
* Regular constructor.
|
||||||
*/
|
*/
|
||||||
public ASTObjectStyleMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro,
|
public ASTMacroDefinition(IASTTranslationUnit parent, IMacroBinding macro,
|
||||||
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
|
int startNumber, int nameNumber, int nameEndNumber, int expansionNumber, int endNumber) {
|
||||||
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, startNumber, endNumber);
|
||||||
fExpansionNumber= expansionNumber;
|
fExpansionNumber= expansionNumber;
|
||||||
|
@ -250,7 +250,7 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
|
||||||
* Constructor for built-in macros
|
* Constructor for built-in macros
|
||||||
* @param expansionOffset
|
* @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);
|
super(parent, IASTTranslationUnit.PREPROCESSOR_STATEMENT, -1, -1);
|
||||||
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, floc, macro.getNameCharArray(), macro);
|
fName= new ASTBuiltinName(this, IASTPreprocessorMacroDefinition.MACRO_NAME, floc, macro.getNameCharArray(), macro);
|
||||||
fExpansionNumber= -1;
|
fExpansionNumber= -1;
|
||||||
|
@ -270,7 +270,12 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExpansion() {
|
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() {
|
public IASTName getName() {
|
||||||
|
@ -306,7 +311,10 @@ class ASTObjectStyleMacroDefinition extends ASTPreprocessorNode implements IASTP
|
||||||
if (fExpansionOffset >= 0) {
|
if (fExpansionOffset >= 0) {
|
||||||
String fileName= fName.getContainingFilename();
|
String fileName= fName.getContainingFilename();
|
||||||
if (fileName != null) {
|
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;
|
return null;
|
||||||
|
@ -328,7 +336,7 @@ class ASTMacroParameter extends ASTPreprocessorNode implements IASTFunctionStyle
|
||||||
public void setParameter(String value) {assert false;}
|
public void setParameter(String value) {assert false;}
|
||||||
}
|
}
|
||||||
|
|
||||||
class ASTFunctionStyleMacroDefinition extends ASTObjectStyleMacroDefinition implements IASTPreprocessorFunctionStyleMacroDefinition {
|
class ASTFunctionStyleMacroDefinition extends ASTMacroDefinition implements IASTPreprocessorFunctionStyleMacroDefinition {
|
||||||
/**
|
/**
|
||||||
* Regular constructor.
|
* Regular constructor.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -14,8 +14,6 @@ package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.text.DateFormatSymbols;
|
|
||||||
import java.util.Calendar;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
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 tNOSPACE= IToken.FIRST_RESERVED_PREPROCESSOR+4;
|
||||||
public static final int tMACRO_PARAMETER= IToken.FIRST_RESERVED_PREPROCESSOR+5;
|
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_PREPROCESSOR_DIRECTIVE = OffsetLimitReachedException.ORIGIN_PREPROCESSOR_DIRECTIVE;
|
||||||
private static final int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE;
|
private static final int ORIGIN_INACTIVE_CODE = OffsetLimitReachedException.ORIGIN_INACTIVE_CODE;
|
||||||
// private static final int ORIGIN_MACRO_EXPANSION = OffsetLimitReachedException.ORIGIN_MACRO_EXPANSION;
|
// 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_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 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 {
|
private interface IIncludeFileTester {
|
||||||
Object checkFile(String path, String fileName);
|
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 IParserLogService fLog;
|
||||||
final private IIndexBasedCodeReaderFactory fCodeReaderFactory;
|
final private IIndexBasedCodeReaderFactory fCodeReaderFactory;
|
||||||
private final ExpressionEvaluator fExpressionEvaluator;
|
private final ExpressionEvaluator fExpressionEvaluator;
|
||||||
|
|
|
@ -48,7 +48,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
private ArrayList<ASTPreprocessorNode> fDirectives= new ArrayList<ASTPreprocessorNode>();
|
private ArrayList<ASTPreprocessorNode> fDirectives= new ArrayList<ASTPreprocessorNode>();
|
||||||
private ArrayList<ASTProblem> fProblems= new ArrayList<ASTProblem>();
|
private ArrayList<ASTProblem> fProblems= new ArrayList<ASTProblem>();
|
||||||
private ArrayList<ASTComment> fComments= new ArrayList<ASTComment>();
|
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 ArrayList<IASTName> fMacroReferences= new ArrayList<IASTName>();
|
||||||
|
|
||||||
private LocationCtxFile fRootContext= null;
|
private LocationCtxFile fRootContext= null;
|
||||||
|
@ -69,12 +69,12 @@ public class LocationMap implements ILocationResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerPredefinedMacro(IMacroBinding macro, IASTFileLocation nameloc, int expansionOffset) {
|
private void registerPredefinedMacro(IMacroBinding macro, IASTFileLocation nameloc, int expansionOffset) {
|
||||||
ASTObjectStyleMacroDefinition astmacro;
|
ASTMacroDefinition astmacro;
|
||||||
if (macro.isFunctionStyle()) {
|
if (macro.isFunctionStyle()) {
|
||||||
astmacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
astmacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
astmacro= new ASTObjectStyleMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
astmacro= new ASTMacroDefinition(fTranslationUnit, macro, nameloc, expansionOffset);
|
||||||
}
|
}
|
||||||
fBuiltinMacros.add(astmacro);
|
fBuiltinMacros.add(astmacro);
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ public class LocationMap implements ILocationResolver {
|
||||||
endOffset= getSequenceNumberForOffset(endOffset);
|
endOffset= getSequenceNumberForOffset(endOffset);
|
||||||
ASTPreprocessorNode astMacro;
|
ASTPreprocessorNode astMacro;
|
||||||
if (!macrodef.isFunctionStyle()) {
|
if (!macrodef.isFunctionStyle()) {
|
||||||
astMacro= new ASTObjectStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
|
astMacro= new ASTMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
|
astMacro= new ASTFunctionStyleMacroDefinition(fTranslationUnit, macrodef, startOffset, nameOffset, nameEndOffset, expansionOffset, endOffset);
|
||||||
|
|
|
@ -136,6 +136,11 @@ public class MacroExpander {
|
||||||
private int fStartOffset;
|
private int fStartOffset;
|
||||||
private int fEndOffset;
|
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) {
|
public MacroExpander(ILexerLog log, CharArrayMap<PreprocessorMacro> macroDictionary, LocationMap locationMap, LexerOptions lexOptions) {
|
||||||
fDictionary= macroDictionary;
|
fDictionary= macroDictionary;
|
||||||
fLocationMap= locationMap;
|
fLocationMap= locationMap;
|
||||||
|
@ -173,10 +178,13 @@ public class MacroExpander {
|
||||||
* Method for tracking macro expansions.
|
* Method for tracking macro expansions.
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
public void expand(String beforeExpansion, MacroExpansionTracker tracker) {
|
public void expand(String beforeExpansion, MacroExpansionTracker tracker, String filePath, int lineNumber) {
|
||||||
Lexer lexer= new Lexer(beforeExpansion.toCharArray(), fLexOptions, fLog, this);
|
|
||||||
fImplicitMacroExpansions.clear();
|
fImplicitMacroExpansions.clear();
|
||||||
fImageLocationInfos.clear();
|
fImageLocationInfos.clear();
|
||||||
|
fFixedInput= beforeExpansion.toCharArray();
|
||||||
|
fFixedCurrentFilename= filePath;
|
||||||
|
fFixedLineNumber= lineNumber;
|
||||||
|
Lexer lexer= new Lexer(fFixedInput, fLexOptions, fLog, this);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
tracker.start(lexer);
|
tracker.start(lexer);
|
||||||
|
@ -362,17 +370,28 @@ public class MacroExpander {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSpacemarker(Token l, Token t, TokenList target) {
|
private static boolean isNeighborInSource(Token l, Token t) {
|
||||||
if (l != null && t != null) {
|
if (l != null && t != null) {
|
||||||
final Object s1= l.fSource;
|
final Object s1= l.fSource;
|
||||||
final Object s2= t.fSource;
|
final Object s2= t.fSource;
|
||||||
if (s1 == s2 && s1 != null && l.getType() != CPreprocessor.tSPACE) {
|
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()) {
|
if (l.getEndOffset() == t.getOffset()) {
|
||||||
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
|
target.append(new Token(CPreprocessor.tNOSPACE, null, 0, 0));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
target.append(new Token(CPreprocessor.tSPACE, s1, l.getEndOffset(), t.getOffset()));
|
target.append(new Token(CPreprocessor.tSPACE, l.fSource, l.getEndOffset(), t.getOffset()));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -397,7 +416,7 @@ public class MacroExpander {
|
||||||
boolean complete= false;
|
boolean complete= false;
|
||||||
boolean isFirstOfArg= true;
|
boolean isFirstOfArg= true;
|
||||||
Token lastToken= null;
|
Token lastToken= null;
|
||||||
Token spaceMarker= null;
|
TokenList spaceMarkers= new TokenList();
|
||||||
loop: while (true) {
|
loop: while (true) {
|
||||||
Token t= input.fetchFirst();
|
Token t= input.fetchFirst();
|
||||||
if (t == null) {
|
if (t == null) {
|
||||||
|
@ -408,6 +427,7 @@ public class MacroExpander {
|
||||||
case IToken.tEND_OF_INPUT:
|
case IToken.tEND_OF_INPUT:
|
||||||
case IToken.tCOMPLETION:
|
case IToken.tCOMPLETION:
|
||||||
case CPreprocessor.tSCOPE_MARKER:
|
case CPreprocessor.tSCOPE_MARKER:
|
||||||
|
case Lexer.tNEWLINE:
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tracker.addFunctionStyleMacroExpansionToken((Token) t.clone());
|
tracker.addFunctionStyleMacroExpansionToken((Token) t.clone());
|
||||||
|
@ -449,7 +469,7 @@ public class MacroExpander {
|
||||||
if (nesting == 0) {
|
if (nesting == 0) {
|
||||||
if (idx < argCount-1) { // next argument
|
if (idx < argCount-1) { // next argument
|
||||||
isFirstOfArg= true;
|
isFirstOfArg= true;
|
||||||
spaceMarker= null;
|
spaceMarkers.clear();
|
||||||
idx++;
|
idx++;
|
||||||
continue loop;
|
continue loop;
|
||||||
}
|
}
|
||||||
|
@ -471,7 +491,7 @@ public class MacroExpander {
|
||||||
case CPreprocessor.tSPACE:
|
case CPreprocessor.tSPACE:
|
||||||
case CPreprocessor.tNOSPACE:
|
case CPreprocessor.tNOSPACE:
|
||||||
if (!isFirstOfArg) {
|
if (!isFirstOfArg) {
|
||||||
spaceMarker= t;
|
spaceMarkers.append(t);
|
||||||
}
|
}
|
||||||
continue loop;
|
continue loop;
|
||||||
|
|
||||||
|
@ -481,10 +501,7 @@ public class MacroExpander {
|
||||||
if (argCount == 0) {
|
if (argCount == 0) {
|
||||||
break loop;
|
break loop;
|
||||||
}
|
}
|
||||||
if (spaceMarker != null) {
|
result[idx].appendAll(spaceMarkers);
|
||||||
result[idx].append(spaceMarker);
|
|
||||||
spaceMarker= null;
|
|
||||||
}
|
|
||||||
result[idx].append(t);
|
result[idx].append(t);
|
||||||
isFirstOfArg= false;
|
isFirstOfArg= false;
|
||||||
}
|
}
|
||||||
|
@ -500,7 +517,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void replaceArgs(PreprocessorMacro macro, TokenList[] args, TokenList[] expandedArgs, TokenList result) {
|
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 l= null;
|
||||||
Token n;
|
Token n;
|
||||||
|
@ -638,7 +655,7 @@ public class MacroExpander {
|
||||||
|
|
||||||
private BitSet getParamUsage(PreprocessorMacro macro) {
|
private BitSet getParamUsage(PreprocessorMacro macro) {
|
||||||
final BitSet result= new BitSet();
|
final BitSet result= new BitSet();
|
||||||
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions);
|
final TokenList replacement= macro.getTokens(fDefinitionParser, fLexOptions, this);
|
||||||
|
|
||||||
Token l= null;
|
Token l= null;
|
||||||
Token n;
|
Token n;
|
||||||
|
@ -684,7 +701,7 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void objStyleTokenPaste(PreprocessorMacro macro, TokenList result) {
|
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 l= null;
|
||||||
Token n;
|
Token n;
|
||||||
|
@ -862,9 +879,33 @@ public class MacroExpander {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean hasImplicitSpace(Token l, Token t) {
|
int getCurrentLineNumber() {
|
||||||
return l != null &&
|
if (fFixedInput != null) {
|
||||||
l.fSource != null && l.fSource == t.fSource &&
|
return fFixedLineNumber + countNewlines(fFixedInput);
|
||||||
l.getEndOffset() != t.getOffset() && t.getType() != CPreprocessor.tSPACE;
|
}
|
||||||
|
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$
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -252,7 +252,9 @@ public class MacroExpansionTracker {
|
||||||
TokenList p = minfo.fArguments.get(pcount);
|
TokenList p = minfo.fArguments.get(pcount);
|
||||||
if (p != null) {
|
if (p != null) {
|
||||||
active = false;
|
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);
|
result.appendAll(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -261,7 +263,7 @@ public class MacroExpansionTracker {
|
||||||
|
|
||||||
case IToken.tRPAREN:
|
case IToken.tRPAREN:
|
||||||
if (!active && nesting == 0) {
|
if (!active && nesting == 0) {
|
||||||
addSpacemarker(l, t, result);
|
MacroExpander.addSpacemarker(l, t, result);
|
||||||
active= true;
|
active= true;
|
||||||
}
|
}
|
||||||
if (active) {
|
if (active) {
|
||||||
|
@ -276,13 +278,15 @@ public class MacroExpansionTracker {
|
||||||
if (nesting == 0) {
|
if (nesting == 0) {
|
||||||
if (++pcount < minfo.fArguments.size()) {
|
if (++pcount < minfo.fArguments.size()) {
|
||||||
if (!active) {
|
if (!active) {
|
||||||
addSpacemarker(l, t, result);
|
MacroExpander.addSpacemarker(l, t, result);
|
||||||
}
|
}
|
||||||
result.append(t);
|
result.append(t);
|
||||||
TokenList p = minfo.fArguments.get(pcount);
|
TokenList p = minfo.fArguments.get(pcount);
|
||||||
active = p == null;
|
active = p == null;
|
||||||
if (!active) {
|
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);
|
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.
|
* Informs the tracker that the function style macro has been expanded.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -49,6 +49,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
private final char[] fSource;
|
private final char[] fSource;
|
||||||
private final int[] fBoundaries;
|
private final int[] fBoundaries;
|
||||||
private final SingleMacroExpansionExplorer[] fDelegates;
|
private final SingleMacroExpansionExplorer[] fDelegates;
|
||||||
|
private String fFilePath;
|
||||||
|
|
||||||
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
|
public MultiMacroExpansionExplorer(IASTTranslationUnit tu, IASTFileLocation loc) {
|
||||||
if (tu == null || loc == null || loc.getNodeLength() == 0) {
|
if (tu == null || loc == null || loc.getNodeLength() == 0) {
|
||||||
|
@ -75,6 +76,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fFilePath= tu.getFilePath();
|
||||||
fSource= resolver.getUnpreprocessedSignature(loc);
|
fSource= resolver.getUnpreprocessedSignature(loc);
|
||||||
fBoundaries= new int[count*2+1];
|
fBoundaries= new int[count*2+1];
|
||||||
fDelegates= new SingleMacroExpansionExplorer[count];
|
fDelegates= new SingleMacroExpansionExplorer[count];
|
||||||
|
@ -91,7 +93,7 @@ public class MultiMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
fBoundaries[++bidx]= from;
|
fBoundaries[++bidx]= from;
|
||||||
fBoundaries[++bidx]= to;
|
fBoundaries[++bidx]= to;
|
||||||
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from), ref,
|
fDelegates[++didx]= new SingleMacroExpansionExplorer(new String(fSource, from, to-from), ref,
|
||||||
resolver.getImplicitMacroReferences(ref));
|
resolver.getImplicitMacroReferences(ref), fFilePath, refLoc.getStartingLineNumber());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fBoundaries[++bidx]= fSource.length;
|
fBoundaries[++bidx]= fSource.length;
|
||||||
|
|
|
@ -10,9 +10,13 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
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.ILinkage;
|
||||||
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
import org.eclipse.cdt.core.dom.ast.IMacroBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IScope;
|
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.Keywords;
|
||||||
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
|
@ -83,27 +87,7 @@ abstract class PreprocessorMacro implements IMacroBinding {
|
||||||
buf.append(')');
|
buf.append(')');
|
||||||
return buf.toString();
|
return buf.toString();
|
||||||
}
|
}
|
||||||
public abstract TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions);
|
public abstract TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions, MacroExpander expander);
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjectStyleMacro extends PreprocessorMacro {
|
class ObjectStyleMacro extends PreprocessorMacro {
|
||||||
|
@ -158,7 +142,7 @@ class ObjectStyleMacro extends PreprocessorMacro {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions) {
|
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions, MacroExpander expander) {
|
||||||
if (fExpansionTokens == null) {
|
if (fExpansionTokens == null) {
|
||||||
fExpansionTokens= new TokenList();
|
fExpansionTokens= new TokenList();
|
||||||
Lexer lex= new Lexer(fExpansion, fExpansionOffset, fEndOffset, lexOptions, ILexerLog.NULL, this);
|
Lexer lex= new Lexer(fExpansion, fExpansionOffset, fEndOffset, lexOptions, ILexerLog.NULL, this);
|
||||||
|
@ -267,3 +251,90 @@ class FunctionStyleMacro extends ObjectStyleMacro {
|
||||||
return true;
|
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());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,15 +32,17 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
private final CharArrayMap<PreprocessorMacro> fDictionary;
|
private final CharArrayMap<PreprocessorMacro> fDictionary;
|
||||||
private MacroExpansionStep fFullExpansion;
|
private MacroExpansionStep fFullExpansion;
|
||||||
private int fExpansionCount;
|
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;
|
fInput= input;
|
||||||
fDictionary= createDictionary(ref, implicitRefs);
|
fDictionary= createDictionary(ref, implicitRefs);
|
||||||
|
fFilePath= filePath;
|
||||||
|
fLineNumber= lineNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
private CharArrayMap<PreprocessorMacro> createDictionary(IASTName ref, IASTName[] implicitRefs) {
|
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);
|
CharArrayMap<PreprocessorMacro> map= new CharArrayMap<PreprocessorMacro>(implicitRefs.length+1);
|
||||||
addMacroDefinition(map, ref);
|
addMacroDefinition(map, ref);
|
||||||
for (IASTName name : implicitRefs) {
|
for (IASTName name : implicitRefs) {
|
||||||
|
@ -71,7 +73,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
private void computeExpansion() {
|
private void computeExpansion() {
|
||||||
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
|
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
|
||||||
MacroExpansionTracker tracker= new MacroExpansionTracker(Integer.MAX_VALUE);
|
MacroExpansionTracker tracker= new MacroExpansionTracker(Integer.MAX_VALUE);
|
||||||
expander.expand(fInput, tracker);
|
expander.expand(fInput, tracker, fFilePath, fLineNumber);
|
||||||
|
|
||||||
fExpansionCount= tracker.getStepCount();
|
fExpansionCount= tracker.getStepCount();
|
||||||
ReplaceEdit r= tracker.getReplacement();
|
ReplaceEdit r= tracker.getReplacement();
|
||||||
|
@ -87,7 +89,7 @@ public class SingleMacroExpansionExplorer extends MacroExpansionExplorer {
|
||||||
}
|
}
|
||||||
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
|
MacroExpander expander= new MacroExpander(ILexerLog.NULL, fDictionary, null, LEX_OPTIONS);
|
||||||
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
|
MacroExpansionTracker tracker= new MacroExpansionTracker(step);
|
||||||
expander.expand(fInput, tracker);
|
expander.expand(fInput, tracker, fFilePath, fLineNumber);
|
||||||
|
|
||||||
fExpansionCount= tracker.getStepCount();
|
fExpansionCount= tracker.getStepCount();
|
||||||
ReplaceEdit r= tracker.getReplacement();
|
ReplaceEdit r= tracker.getReplacement();
|
||||||
|
|
|
@ -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
|
* All rights reserved. This program and the accompanying materials
|
||||||
* are made available under the terms of the Eclipse Public License v1.0
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
* which accompanies this distribution, and is available at
|
* which accompanies this distribution, and is available at
|
||||||
|
@ -121,4 +121,8 @@ class TokenList {
|
||||||
fLast= l;
|
fLast= l;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
fFirst= fLast= null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -173,7 +173,7 @@ public class PDOMMacro implements IIndexMacro, IASTFileLocation {
|
||||||
fExpansion= getExpansionInDB().getChars();
|
fExpansion= getExpansionInDB().getChars();
|
||||||
} catch (CoreException e) {
|
} catch (CoreException e) {
|
||||||
CCorePlugin.log(e);
|
CCorePlugin.log(e);
|
||||||
fExpansion= new char[] { ' ' };
|
fExpansion= new char[] {};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return fExpansion;
|
return fExpansion;
|
||||||
|
|
Loading…
Add table
Reference in a new issue