mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Made PreprocessorMacro and TokenList public (#676)
### Changes With this PR, `PreprocessorMacro` and its subclasses are no longer package-private but public instead. Same goes for `TokenList`. ### Reasons for the changes When parsing C/C++ code with CDT as a standalone library I want to track certain macro expansions using the [MacroExpander](https://github.com/eclipse-cdt/cdt/blob/main/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/MacroExpander.java). It is not actually part of the public API but declared as `public`. It takes an argument `macroDictionary` of type `CharArrayMap<PreprocessorMacro>` in its constructor. Currently, `PreprocessorMacro` is package-privat and thus, not available without shadowing (i.e., implementing my custom macro tracker in the package `org.eclipse.cdt.internal.core.parser.scanner`). It questionable whether it is a good design decision to have public and private API mixed together here (rendering the usage of the constructor of `MacroExpander` impossible). Also, another problem occurs once you take the route of shadowing to have access to `PreprocessorMacro`: the CDT jars are all signed during release (makes sense) but, sadly speaking, that will result in a `SecurityException` when trying to call their API from your own (unsigned) code which lives in the shadowed package (in my case in `org.eclipse.cdt.internal.core.parser.scanner`). ### Problem solved MacroExpander can now be used from the outside because `PreprocessorMacro` and `TokenList` are no longer package-private. Shadowing is no longer needed. Signed jars are no longer a problem.
This commit is contained in:
parent
5e7ce7e31a
commit
61c3568839
11 changed files with 511 additions and 358 deletions
|
@ -0,0 +1,37 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
|
||||||
|
public final class CounterMacro extends DynamicMacro {
|
||||||
|
private static final char[] ZERO = { '0' };
|
||||||
|
|
||||||
|
private long fValue;
|
||||||
|
|
||||||
|
public CounterMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token execute(MacroExpander expander) {
|
||||||
|
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, String.valueOf(fValue++).toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return ZERO;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import java.text.DateFormatSymbols;
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
|
||||||
|
public final class DateMacro extends DynamicMacro {
|
||||||
|
public DateMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token execute(MacroExpander expander) {
|
||||||
|
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)]);
|
||||||
|
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$
|
||||||
|
charArray = buffer.toString().toCharArray();
|
||||||
|
return charArray;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return createDate();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,49 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
|
||||||
|
public abstract class DynamicMacro extends PreprocessorMacro {
|
||||||
|
|
||||||
|
public DynamicMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final char[] getExpansion() {
|
||||||
|
return getExpansionImage();
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract Token execute(MacroExpander expander);
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions, MacroExpander expander) {
|
||||||
|
TokenList result = new TokenList();
|
||||||
|
result.append(execute(expander));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
final protected void append(StringBuilder buffer, int value) {
|
||||||
|
if (value < 10)
|
||||||
|
buffer.append("0"); //$NON-NLS-1$
|
||||||
|
buffer.append(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isDynamic() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
|
||||||
|
public final class FileMacro extends DynamicMacro {
|
||||||
|
public FileMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token execute(MacroExpander expander) {
|
||||||
|
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
|
||||||
|
buffer.append(expander.getCurrentFilename().replace("\\", "\\\\")); //$NON-NLS-1$//$NON-NLS-2$
|
||||||
|
buffer.append('\"');
|
||||||
|
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return "\"file\"".toCharArray(); //$NON-NLS-1$
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,119 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.Keywords;
|
||||||
|
|
||||||
|
public class FunctionStyleMacro extends ObjectStyleMacro {
|
||||||
|
public static final int NO_VAARGS = 0; // M(a)
|
||||||
|
public static final int VAARGS = 1; // M(...)
|
||||||
|
public static final int NAMED_VAARGS = 2; // M(a...)
|
||||||
|
|
||||||
|
final private char[][] fParamList;
|
||||||
|
final private int fHasVarArgs;
|
||||||
|
private char[] fSignature;
|
||||||
|
|
||||||
|
public FunctionStyleMacro(char[] name, char[][] paramList, int hasVarArgs, char[] expansion) {
|
||||||
|
this(name, paramList, hasVarArgs, 0, expansion.length, null, new CharArray(expansion));
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionStyleMacro(char[] name, char[][] paramList, int hasVarArgs, AbstractCharArray expansion,
|
||||||
|
int expansionOffset, int expansionEndOffset) {
|
||||||
|
this(name, paramList, hasVarArgs, expansionOffset, expansionEndOffset, null, expansion);
|
||||||
|
}
|
||||||
|
|
||||||
|
public FunctionStyleMacro(char[] name, char[][] paramList, int hasVarArgs, int expansionFileOffset,
|
||||||
|
int endFileOffset, TokenList expansion, AbstractCharArray source) {
|
||||||
|
super(name, expansionFileOffset, endFileOffset, expansion, source);
|
||||||
|
fParamList = paramList;
|
||||||
|
fHasVarArgs = hasVarArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[][] getParameterList() {
|
||||||
|
final int length = fParamList.length;
|
||||||
|
if (fHasVarArgs == NO_VAARGS || length == 0) {
|
||||||
|
return fParamList;
|
||||||
|
}
|
||||||
|
char[][] result = new char[length][];
|
||||||
|
System.arraycopy(fParamList, 0, result, 0, length - 1);
|
||||||
|
if (fHasVarArgs == VAARGS) {
|
||||||
|
result[length - 1] = Keywords.cpELLIPSIS;
|
||||||
|
} else {
|
||||||
|
final char[] param = fParamList[length - 1];
|
||||||
|
final int plen = param.length;
|
||||||
|
final int elen = Keywords.cpELLIPSIS.length;
|
||||||
|
final char[] rp = new char[plen + elen];
|
||||||
|
System.arraycopy(param, 0, rp, 0, plen);
|
||||||
|
System.arraycopy(Keywords.cpELLIPSIS, 0, rp, plen, elen);
|
||||||
|
result[length - 1] = rp;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[][] getParameterPlaceholderList() {
|
||||||
|
return fParamList;
|
||||||
|
}
|
||||||
|
|
||||||
|
public char[] getSignature() {
|
||||||
|
if (fSignature != null) {
|
||||||
|
return fSignature;
|
||||||
|
}
|
||||||
|
|
||||||
|
StringBuffer result = new StringBuffer();
|
||||||
|
result.append(getName());
|
||||||
|
result.append('(');
|
||||||
|
|
||||||
|
final int lastIdx = fParamList.length - 1;
|
||||||
|
if (lastIdx >= 0) {
|
||||||
|
for (int i = 0; i < lastIdx; i++) {
|
||||||
|
result.append(fParamList[i]);
|
||||||
|
result.append(',');
|
||||||
|
}
|
||||||
|
switch (fHasVarArgs) {
|
||||||
|
case VAARGS:
|
||||||
|
result.append(Keywords.cpELLIPSIS);
|
||||||
|
break;
|
||||||
|
case NAMED_VAARGS:
|
||||||
|
result.append(fParamList[lastIdx]);
|
||||||
|
result.append(Keywords.cpELLIPSIS);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
result.append(fParamList[lastIdx]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.append(')');
|
||||||
|
final int len = result.length();
|
||||||
|
final char[] sig = new char[len];
|
||||||
|
result.getChars(0, len, sig, 0);
|
||||||
|
fSignature = sig;
|
||||||
|
return sig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns one of {@link FunctionStyleMacro#NO_VAARGS}, {@link #VAARGS} or {@link #NAMED_VAARGS}.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public int hasVarArgs() {
|
||||||
|
return fHasVarArgs;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isFunctionStyle() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,34 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
|
||||||
|
public final class LineMacro extends DynamicMacro {
|
||||||
|
public LineMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token execute(MacroExpander expander) {
|
||||||
|
int lineNumber = expander.getCurrentLineNumber();
|
||||||
|
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return new char[] { '1' };
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,91 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.OffsetLimitReachedException;
|
||||||
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
|
||||||
|
public class ObjectStyleMacro extends PreprocessorMacro {
|
||||||
|
private final AbstractCharArray fExpansion;
|
||||||
|
private final int fExpansionOffset;
|
||||||
|
private final int fEndOffset;
|
||||||
|
private TokenList fExpansionTokens;
|
||||||
|
|
||||||
|
public ObjectStyleMacro(char[] name, char[] expansion) {
|
||||||
|
this(name, 0, expansion.length, null, new CharArray(expansion));
|
||||||
|
}
|
||||||
|
|
||||||
|
public ObjectStyleMacro(char[] name, int expansionOffset, int endOffset, TokenList expansion,
|
||||||
|
AbstractCharArray source) {
|
||||||
|
super(name);
|
||||||
|
fExpansionOffset = expansionOffset;
|
||||||
|
fEndOffset = endOffset;
|
||||||
|
fExpansion = source;
|
||||||
|
fExpansionTokens = expansion;
|
||||||
|
if (expansion != null) {
|
||||||
|
setSource(expansion.first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpansionOffset() {
|
||||||
|
return fExpansionOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpansionEndOffset() {
|
||||||
|
return fEndOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setSource(Token t) {
|
||||||
|
final int shift = -fExpansionOffset;
|
||||||
|
while (t != null) {
|
||||||
|
t.fSource = this;
|
||||||
|
t.shiftOffset(shift);
|
||||||
|
t = (Token) t.getNext();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansion() {
|
||||||
|
return MacroDefinitionParser.getExpansion(fExpansion, fExpansionOffset, fEndOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
final int length = fEndOffset - fExpansionOffset;
|
||||||
|
char[] result = new char[length];
|
||||||
|
fExpansion.arraycopy(fExpansionOffset, result, 0, length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
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);
|
||||||
|
try {
|
||||||
|
lex.nextToken(); // consume the start token
|
||||||
|
mdp.parseExpansion(lex, ILexerLog.NULL, getNameCharArray(), getParameterPlaceholderList(),
|
||||||
|
fExpansionTokens);
|
||||||
|
} catch (OffsetLimitReachedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return fExpansionTokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public final boolean isDynamic() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -14,16 +14,10 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
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.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
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.OffsetLimitReachedException;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.Linkage;
|
import org.eclipse.cdt.internal.core.dom.Linkage;
|
||||||
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
|
||||||
|
@ -31,7 +25,7 @@ import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
* Models macros used by the preprocessor
|
* Models macros used by the preprocessor
|
||||||
* @since 5.0
|
* @since 5.0
|
||||||
*/
|
*/
|
||||||
abstract class PreprocessorMacro implements IMacroBinding {
|
public abstract class PreprocessorMacro implements IMacroBinding {
|
||||||
final private char[] fName;
|
final private char[] fName;
|
||||||
|
|
||||||
public PreprocessorMacro(char[] name) {
|
public PreprocessorMacro(char[] name) {
|
||||||
|
@ -86,7 +80,7 @@ abstract class PreprocessorMacro implements IMacroBinding {
|
||||||
/**
|
/**
|
||||||
* Returns {@link FunctionStyleMacro#NO_VAARGS}
|
* Returns {@link FunctionStyleMacro#NO_VAARGS}
|
||||||
*/
|
*/
|
||||||
int hasVarArgs() {
|
public int hasVarArgs() {
|
||||||
return FunctionStyleMacro.NO_VAARGS;
|
return FunctionStyleMacro.NO_VAARGS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,351 +105,3 @@ abstract class PreprocessorMacro implements IMacroBinding {
|
||||||
|
|
||||||
public abstract TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions, MacroExpander expander);
|
public abstract TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions, MacroExpander expander);
|
||||||
}
|
}
|
||||||
|
|
||||||
class ObjectStyleMacro extends PreprocessorMacro {
|
|
||||||
private final AbstractCharArray fExpansion;
|
|
||||||
final int fExpansionOffset;
|
|
||||||
final int fEndOffset;
|
|
||||||
private TokenList fExpansionTokens;
|
|
||||||
|
|
||||||
public ObjectStyleMacro(char[] name, char[] expansion) {
|
|
||||||
this(name, 0, expansion.length, null, new CharArray(expansion));
|
|
||||||
}
|
|
||||||
|
|
||||||
public ObjectStyleMacro(char[] name, int expansionOffset, int endOffset, TokenList expansion,
|
|
||||||
AbstractCharArray source) {
|
|
||||||
super(name);
|
|
||||||
fExpansionOffset = expansionOffset;
|
|
||||||
fEndOffset = endOffset;
|
|
||||||
fExpansion = source;
|
|
||||||
fExpansionTokens = expansion;
|
|
||||||
if (expansion != null) {
|
|
||||||
setSource(expansion.first());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getExpansionOffset() {
|
|
||||||
return fExpansionOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getExpansionEndOffset() {
|
|
||||||
return fEndOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setSource(Token t) {
|
|
||||||
final int shift = -fExpansionOffset;
|
|
||||||
while (t != null) {
|
|
||||||
t.fSource = this;
|
|
||||||
t.shiftOffset(shift);
|
|
||||||
t = (Token) t.getNext();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansion() {
|
|
||||||
return MacroDefinitionParser.getExpansion(fExpansion, fExpansionOffset, fEndOffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
final int length = fEndOffset - fExpansionOffset;
|
|
||||||
char[] result = new char[length];
|
|
||||||
fExpansion.arraycopy(fExpansionOffset, result, 0, length);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
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);
|
|
||||||
try {
|
|
||||||
lex.nextToken(); // consume the start token
|
|
||||||
mdp.parseExpansion(lex, ILexerLog.NULL, getNameCharArray(), getParameterPlaceholderList(),
|
|
||||||
fExpansionTokens);
|
|
||||||
} catch (OffsetLimitReachedException e) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return fExpansionTokens;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean isDynamic() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class FunctionStyleMacro extends ObjectStyleMacro {
|
|
||||||
public static final int NO_VAARGS = 0; // M(a)
|
|
||||||
public static final int VAARGS = 1; // M(...)
|
|
||||||
public static final int NAMED_VAARGS = 2; // M(a...)
|
|
||||||
|
|
||||||
final private char[][] fParamList;
|
|
||||||
final private int fHasVarArgs;
|
|
||||||
private char[] fSignature;
|
|
||||||
|
|
||||||
public FunctionStyleMacro(char[] name, char[][] paramList, int hasVarArgs, char[] expansion) {
|
|
||||||
this(name, paramList, hasVarArgs, 0, expansion.length, null, new CharArray(expansion));
|
|
||||||
}
|
|
||||||
|
|
||||||
public FunctionStyleMacro(char[] name, char[][] paramList, int hasVarArgs, AbstractCharArray expansion,
|
|
||||||
int expansionOffset, int expansionEndOffset) {
|
|
||||||
this(name, paramList, hasVarArgs, expansionOffset, expansionEndOffset, null, expansion);
|
|
||||||
}
|
|
||||||
|
|
||||||
public FunctionStyleMacro(char[] name, char[][] paramList, int hasVarArgs, int expansionFileOffset,
|
|
||||||
int endFileOffset, TokenList expansion, AbstractCharArray source) {
|
|
||||||
super(name, expansionFileOffset, endFileOffset, expansion, source);
|
|
||||||
fParamList = paramList;
|
|
||||||
fHasVarArgs = hasVarArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[][] getParameterList() {
|
|
||||||
final int length = fParamList.length;
|
|
||||||
if (fHasVarArgs == NO_VAARGS || length == 0) {
|
|
||||||
return fParamList;
|
|
||||||
}
|
|
||||||
char[][] result = new char[length][];
|
|
||||||
System.arraycopy(fParamList, 0, result, 0, length - 1);
|
|
||||||
if (fHasVarArgs == VAARGS) {
|
|
||||||
result[length - 1] = Keywords.cpELLIPSIS;
|
|
||||||
} else {
|
|
||||||
final char[] param = fParamList[length - 1];
|
|
||||||
final int plen = param.length;
|
|
||||||
final int elen = Keywords.cpELLIPSIS.length;
|
|
||||||
final char[] rp = new char[plen + elen];
|
|
||||||
System.arraycopy(param, 0, rp, 0, plen);
|
|
||||||
System.arraycopy(Keywords.cpELLIPSIS, 0, rp, plen, elen);
|
|
||||||
result[length - 1] = rp;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[][] getParameterPlaceholderList() {
|
|
||||||
return fParamList;
|
|
||||||
}
|
|
||||||
|
|
||||||
public char[] getSignature() {
|
|
||||||
if (fSignature != null) {
|
|
||||||
return fSignature;
|
|
||||||
}
|
|
||||||
|
|
||||||
StringBuffer result = new StringBuffer();
|
|
||||||
result.append(getName());
|
|
||||||
result.append('(');
|
|
||||||
|
|
||||||
final int lastIdx = fParamList.length - 1;
|
|
||||||
if (lastIdx >= 0) {
|
|
||||||
for (int i = 0; i < lastIdx; i++) {
|
|
||||||
result.append(fParamList[i]);
|
|
||||||
result.append(',');
|
|
||||||
}
|
|
||||||
switch (fHasVarArgs) {
|
|
||||||
case VAARGS:
|
|
||||||
result.append(Keywords.cpELLIPSIS);
|
|
||||||
break;
|
|
||||||
case NAMED_VAARGS:
|
|
||||||
result.append(fParamList[lastIdx]);
|
|
||||||
result.append(Keywords.cpELLIPSIS);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
result.append(fParamList[lastIdx]);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.append(')');
|
|
||||||
final int len = result.length();
|
|
||||||
final char[] sig = new char[len];
|
|
||||||
result.getChars(0, len, sig, 0);
|
|
||||||
fSignature = sig;
|
|
||||||
return sig;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns one of {@link FunctionStyleMacro#NO_VAARGS}, {@link #VAARGS} or {@link #NAMED_VAARGS}.
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
int hasVarArgs() {
|
|
||||||
return fHasVarArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isFunctionStyle() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class UndefinedMacro extends PreprocessorMacro {
|
|
||||||
public UndefinedMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions, MacroExpander expander) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansion() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isDynamic() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class DynamicMacro extends PreprocessorMacro {
|
|
||||||
|
|
||||||
public DynamicMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final char[] getExpansion() {
|
|
||||||
return getExpansionImage();
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract Token execute(MacroExpander expander);
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public TokenList getTokens(MacroDefinitionParser mdp, LexerOptions lexOptions, MacroExpander expander) {
|
|
||||||
TokenList result = new TokenList();
|
|
||||||
result.append(execute(expander));
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
final protected void append(StringBuilder buffer, int value) {
|
|
||||||
if (value < 10)
|
|
||||||
buffer.append("0"); //$NON-NLS-1$
|
|
||||||
buffer.append(value);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public final boolean isDynamic() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class DateMacro extends DynamicMacro {
|
|
||||||
DateMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Token execute(MacroExpander expander) {
|
|
||||||
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)]);
|
|
||||||
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$
|
|
||||||
charArray = buffer.toString().toCharArray();
|
|
||||||
return charArray;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
return createDate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class FileMacro extends DynamicMacro {
|
|
||||||
FileMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Token execute(MacroExpander expander) {
|
|
||||||
StringBuffer buffer = new StringBuffer("\""); //$NON-NLS-1$
|
|
||||||
buffer.append(expander.getCurrentFilename().replace("\\", "\\\\")); //$NON-NLS-1$//$NON-NLS-2$
|
|
||||||
buffer.append('\"');
|
|
||||||
return new TokenWithImage(IToken.tSTRING, null, 0, 0, buffer.toString().toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
return "\"file\"".toCharArray(); //$NON-NLS-1$
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class LineMacro extends DynamicMacro {
|
|
||||||
LineMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Token execute(MacroExpander expander) {
|
|
||||||
int lineNumber = expander.getCurrentLineNumber();
|
|
||||||
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, Long.toString(lineNumber).toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
return new char[] { '1' };
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class TimeMacro extends DynamicMacro {
|
|
||||||
TimeMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Token execute(MacroExpander expander) {
|
|
||||||
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$
|
|
||||||
append(buffer, cal.get(Calendar.MINUTE));
|
|
||||||
buffer.append(":"); //$NON-NLS-1$
|
|
||||||
append(buffer, cal.get(Calendar.SECOND));
|
|
||||||
buffer.append("\""); //$NON-NLS-1$
|
|
||||||
return buffer.toString().toCharArray();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
return createDate();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
final class CounterMacro extends DynamicMacro {
|
|
||||||
private static final char[] ZERO = { '0' };
|
|
||||||
|
|
||||||
private long fValue;
|
|
||||||
|
|
||||||
CounterMacro(char[] name) {
|
|
||||||
super(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Token execute(MacroExpander expander) {
|
|
||||||
return new TokenWithImage(IToken.tINTEGER, null, 0, 0, String.valueOf(fValue++).toCharArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public char[] getExpansionImage() {
|
|
||||||
return ZERO;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.parser.IToken;
|
||||||
|
|
||||||
|
public final class TimeMacro extends DynamicMacro {
|
||||||
|
public TimeMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Token execute(MacroExpander expander) {
|
||||||
|
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$
|
||||||
|
append(buffer, cal.get(Calendar.MINUTE));
|
||||||
|
buffer.append(":"); //$NON-NLS-1$
|
||||||
|
append(buffer, cal.get(Calendar.SECOND));
|
||||||
|
buffer.append("\""); //$NON-NLS-1$
|
||||||
|
return buffer.toString().toCharArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return createDate();
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.parser.scanner;
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
class TokenList {
|
public class TokenList {
|
||||||
private Token fFirst;
|
private Token fFirst;
|
||||||
private Token fLast;
|
private Token fLast;
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ class TokenList {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void cutAfter(Token l) {
|
public void cutAfter(Token l) {
|
||||||
if (l == null) {
|
if (l == null) {
|
||||||
fFirst = null;
|
fFirst = null;
|
||||||
fLast = null;
|
fLast = null;
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2007, 2020 Wind River Systems, Inc. and others.
|
||||||
|
*
|
||||||
|
* This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License 2.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* https://www.eclipse.org/legal/epl-2.0/
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: EPL-2.0
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
* Alexander Fedorov (ArSysOp) - Bug 561992
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.parser.scanner.Lexer.LexerOptions;
|
||||||
|
|
||||||
|
public final class UndefinedMacro extends PreprocessorMacro {
|
||||||
|
public UndefinedMacro(char[] name) {
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TokenList getTokens(MacroDefinitionParser parser, LexerOptions lexOptions, MacroExpander expander) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansion() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public char[] getExpansionImage() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isDynamic() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Reference in a new issue