mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-11 02:05:39 +02:00
Configuring framework search, bug 69529.
This commit is contained in:
parent
24b07e23d7
commit
031bf4556a
7 changed files with 204 additions and 63 deletions
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 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
|
||||||
|
@ -49,6 +49,7 @@ public class InclusionTests extends PreprocessorTestsBase {
|
||||||
super(name);
|
super(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
protected void tearDown() throws Exception {
|
protected void tearDown() throws Exception {
|
||||||
if (fProject != null) {
|
if (fProject != null) {
|
||||||
CProjectHelper.delete(fProject);
|
CProjectHelper.delete(fProject);
|
||||||
|
@ -77,6 +78,36 @@ public class InclusionTests extends PreprocessorTestsBase {
|
||||||
return folder;
|
return folder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// #include "one.h"
|
||||||
|
// #include "f1/two.h"
|
||||||
|
// #include "f1/f2/three.h"
|
||||||
|
public void testIncludeVariables() throws Exception {
|
||||||
|
String content= getAboveComment();
|
||||||
|
|
||||||
|
IFolder f0 = importFolder(".framework");
|
||||||
|
importFolder("f1.framework");
|
||||||
|
importFolder("f1");
|
||||||
|
importFolder("f1/f2.framework");
|
||||||
|
importFolder("f3");
|
||||||
|
IFile base = importFile("base.cpp", content);
|
||||||
|
|
||||||
|
importFile(".framework/one.h", "1");
|
||||||
|
importFile("f1.framework/two.h", "2");
|
||||||
|
importFile("f1/f2.framework/three.h", "3");
|
||||||
|
|
||||||
|
String[] path = {
|
||||||
|
f0.getLocation().removeLastSegments(1) + "/__framework__.framework/__filename__"
|
||||||
|
};
|
||||||
|
IScannerInfo scannerInfo = new ExtendedScannerInfo(Collections.EMPTY_MAP, path, new String[]{}, null);
|
||||||
|
CodeReader reader= new CodeReader(base.getLocation().toString());
|
||||||
|
initializeScanner(reader, ParserLanguage.C, ParserMode.COMPLETE_PARSE, scannerInfo);
|
||||||
|
|
||||||
|
// first file is not picked up (no framework)
|
||||||
|
validateInteger("2");
|
||||||
|
// third file is not picked up (framework must be a single folder)
|
||||||
|
validateEOF();
|
||||||
|
}
|
||||||
|
|
||||||
public void testIncludeNext() throws Exception {
|
public void testIncludeNext() throws Exception {
|
||||||
String baseFile = "int zero; \n#include \"foo.h\""; //$NON-NLS-1$
|
String baseFile = "int zero; \n#include \"foo.h\""; //$NON-NLS-1$
|
||||||
String i1Next = "int one; \n#include_next <bar/foo.h>"; //$NON-NLS-1$
|
String i1Next = "int one; \n#include_next <bar/foo.h>"; //$NON-NLS-1$
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2007, 2008 Wind River Systems, Inc. and others.
|
* Copyright (c) 2007, 2009 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
|
||||||
|
@ -88,9 +88,17 @@ public abstract class PreprocessorTestsBase extends BaseTestCase {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void initializeScanner() throws Exception {
|
protected void initializeScanner() throws Exception {
|
||||||
|
initializeScanner(getAboveComment());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StringBuffer[] getTestContent(int sections) throws IOException {
|
||||||
StringBuffer[] input= TestSourceReader.getContentsForTest(
|
StringBuffer[] input= TestSourceReader.getContentsForTest(
|
||||||
CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), 1);
|
CTestPlugin.getDefault().getBundle(), "parser", getClass(), getName(), sections);
|
||||||
initializeScanner(input[0].toString());
|
return input;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String getAboveComment() throws IOException {
|
||||||
|
return getTestContent(1)[0].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void fullyTokenize() throws Exception {
|
protected void fullyTokenize() throws Exception {
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2002, 2008 IBM Corporation and others.
|
* Copyright (c) 2002, 2009 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
|
||||||
|
@ -30,6 +30,15 @@ public interface IScannerInfo {
|
||||||
/**
|
/**
|
||||||
* Returns an array of paths that are searched when processing an include directive.
|
* Returns an array of paths that are searched when processing an include directive.
|
||||||
* see {@link IExtendedScannerInfo#getLocalIncludePath()}
|
* see {@link IExtendedScannerInfo#getLocalIncludePath()}
|
||||||
|
*
|
||||||
|
* In order to handle framework includes used on Apple Computers you can make use of
|
||||||
|
* the two variables: '__framework__' and '__filename__'.
|
||||||
|
* <br> E.g.: /System/Library/Frameworks/__framework__.framework/Headers/__filename__,
|
||||||
|
* /System/Library/Frameworks/__framework__.framework/PrivateHeaders/__filename__
|
||||||
|
* would handle the framework search for '/System/Library/Frameworks'
|
||||||
|
*
|
||||||
|
* The variables are handled only, if a search path element makes use of both of the variables.
|
||||||
|
* Such a search path element is not used for directives that are not of the form 'folder/name'.
|
||||||
*/
|
*/
|
||||||
public String[] getIncludePaths();
|
public String[] getIncludePaths();
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,6 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
private static final char[] EMPTY_CHAR_ARRAY = new char[0];
|
private static final char[] EMPTY_CHAR_ARRAY = new char[0];
|
||||||
private static final char[] ONE = "1".toCharArray(); //$NON-NLS-1$
|
private static final char[] ONE = "1".toCharArray(); //$NON-NLS-1$
|
||||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
|
||||||
|
|
||||||
|
|
||||||
// standard built-ins
|
// standard built-ins
|
||||||
|
@ -96,15 +95,15 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
private static final Token END_OF_INPUT = new Token(IToken.tEND_OF_INPUT, null, 0, 0);
|
private static final Token END_OF_INPUT = new Token(IToken.tEND_OF_INPUT, null, 0, 0);
|
||||||
|
|
||||||
private interface IIncludeFileTester<T> {
|
private interface IIncludeFileTester<T> {
|
||||||
T checkFile(String path, String fileName, boolean isHeuristicMatch);
|
T checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
|
final private IIncludeFileTester<IncludeFileContent> createCodeReaderTester= new IIncludeFileTester<IncludeFileContent>() {
|
||||||
public IncludeFileContent checkFile(String path, String fileName, boolean isHeuristicMatch) {
|
public IncludeFileContent checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||||
final String finalPath = ScannerUtility.createReconciledPath(path, fileName);
|
final IncludeFileContent fc= fCodeReaderFactory.getContentForInclusion(path);
|
||||||
final IncludeFileContent fc= fCodeReaderFactory.getContentForInclusion(finalPath);
|
|
||||||
if (fc != null) {
|
if (fc != null) {
|
||||||
fc.setFoundByHeuristics(isHeuristicMatch);
|
fc.setFoundByHeuristics(isHeuristicMatch);
|
||||||
|
fc.setFoundOnPath(onPath);
|
||||||
}
|
}
|
||||||
return fc;
|
return fc;
|
||||||
}
|
}
|
||||||
|
@ -112,12 +111,11 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
private static class IncludeResolution {String fLocation; boolean fHeuristic;}
|
private static class IncludeResolution {String fLocation; boolean fHeuristic;}
|
||||||
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
final private IIncludeFileTester<IncludeResolution> createPathTester= new IIncludeFileTester<IncludeResolution>() {
|
||||||
public IncludeResolution checkFile(String path, String fileName, boolean isHeuristicMatch) {
|
public IncludeResolution checkFile(String path, boolean isHeuristicMatch, IncludeSearchPathElement onPath) {
|
||||||
String finalPath= ScannerUtility.createReconciledPath(path, fileName);
|
if (fCodeReaderFactory.getInclusionExists(path)) {
|
||||||
if (fCodeReaderFactory.getInclusionExists(finalPath)) {
|
|
||||||
IncludeResolution res= new IncludeResolution();
|
IncludeResolution res= new IncludeResolution();
|
||||||
res.fHeuristic= isHeuristicMatch;
|
res.fHeuristic= isHeuristicMatch;
|
||||||
res.fLocation= finalPath;
|
res.fLocation= path;
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -168,8 +166,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
final private char[] fAdditionalNumericLiteralSuffixes;
|
final private char[] fAdditionalNumericLiteralSuffixes;
|
||||||
final private CharArrayIntMap fKeywords;
|
final private CharArrayIntMap fKeywords;
|
||||||
final private CharArrayIntMap fPPKeywords;
|
final private CharArrayIntMap fPPKeywords;
|
||||||
final private String[] fIncludePaths;
|
private IncludeSearchPathElement[] fIncludeSearchPath;
|
||||||
final private String[] fQuoteIncludePaths;
|
|
||||||
private String[][] fPreIncludedFiles= null;
|
private String[][] fPreIncludedFiles= null;
|
||||||
|
|
||||||
private int fContentAssistLimit= -1;
|
private int fContentAssistLimit= -1;
|
||||||
|
@ -206,9 +203,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fKeywords= new CharArrayIntMap(40, -1);
|
fKeywords= new CharArrayIntMap(40, -1);
|
||||||
fPPKeywords= new CharArrayIntMap(40, -1);
|
fPPKeywords= new CharArrayIntMap(40, -1);
|
||||||
configureKeywords(language, configuration);
|
configureKeywords(language, configuration);
|
||||||
|
configureIncludeSearchPath(info);
|
||||||
fIncludePaths= info.getIncludePaths();
|
|
||||||
fQuoteIncludePaths= getQuoteIncludePath(info);
|
|
||||||
|
|
||||||
fExpressionEvaluator= new ExpressionEvaluator();
|
fExpressionEvaluator= new ExpressionEvaluator();
|
||||||
fMacroDefinitionParser= new MacroDefinitionParser();
|
fMacroDefinitionParser= new MacroDefinitionParser();
|
||||||
|
@ -318,18 +313,25 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
return array == null ? EMPTY_CHAR_ARRAY : array;
|
return array == null ? EMPTY_CHAR_ARRAY : array;
|
||||||
}
|
}
|
||||||
|
|
||||||
private String[] getQuoteIncludePath(IScannerInfo info) {
|
private void configureIncludeSearchPath(IScannerInfo info) {
|
||||||
|
String[] searchPath= info.getIncludePaths();
|
||||||
|
int idx= 0;
|
||||||
if (info instanceof IExtendedScannerInfo) {
|
if (info instanceof IExtendedScannerInfo) {
|
||||||
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
|
final IExtendedScannerInfo einfo= (IExtendedScannerInfo) info;
|
||||||
final String[] qip= einfo.getLocalIncludePath();
|
final String[] quoteIncludeSearchPath= einfo.getLocalIncludePath();
|
||||||
if (qip != null && qip.length > 0) {
|
if (quoteIncludeSearchPath != null && quoteIncludeSearchPath.length > 0) {
|
||||||
final String[] result= new String[qip.length + fIncludePaths.length];
|
fIncludeSearchPath= new IncludeSearchPathElement[quoteIncludeSearchPath.length + searchPath.length];
|
||||||
System.arraycopy(qip, 0, result, 0, qip.length);
|
for (String qip : quoteIncludeSearchPath) {
|
||||||
System.arraycopy(fIncludePaths, 0, result, qip.length, fIncludePaths.length);
|
fIncludeSearchPath[idx++]= new IncludeSearchPathElement(qip, true);
|
||||||
return result;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return info.getIncludePaths();
|
if (fIncludeSearchPath == null) {
|
||||||
|
fIncludeSearchPath= new IncludeSearchPathElement[searchPath.length];
|
||||||
|
}
|
||||||
|
for (String path : searchPath) {
|
||||||
|
fIncludeSearchPath[idx++]= new IncludeSearchPathElement(path, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info, ParserLanguage lang) {
|
private void setupMacroDictionary(IScannerExtensionConfiguration config, IScannerInfo info, ParserLanguage lang) {
|
||||||
|
@ -872,20 +874,20 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private <T> T findInclusion(final String filename, final boolean quoteInclude,
|
private <T> T findInclusion(final String includeDirective, final boolean quoteInclude,
|
||||||
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
|
final boolean includeNext, final String currentFile, final IIncludeFileTester<T> tester) {
|
||||||
T reader = null;
|
T reader = null;
|
||||||
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
// filename is an absolute path or it is a Linux absolute path on a windows machine
|
||||||
if (new File(filename).isAbsolute() || filename.startsWith("/")) { //$NON-NLS-1$
|
if (new File(includeDirective).isAbsolute() || includeDirective.startsWith("/")) { //$NON-NLS-1$
|
||||||
return tester.checkFile(EMPTY_STRING, filename, false);
|
return tester.checkFile(includeDirective, false, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (currentFile != null && quoteInclude && !includeNext) {
|
if (currentFile != null && quoteInclude && !includeNext) {
|
||||||
// Check to see if we find a match in the current directory
|
// Check to see if we find a match in the current directory
|
||||||
final File currentDir= new File(currentFile).getParentFile();
|
final File currentDir= new File(currentFile).getParentFile();
|
||||||
if (currentDir != null) {
|
if (currentDir != null) {
|
||||||
String absolutePath = currentDir.getAbsolutePath();
|
final String fileLocation = ScannerUtility.createReconciledPath(currentDir.getAbsolutePath(), includeDirective);
|
||||||
reader = tester.checkFile(absolutePath, filename, false);
|
reader = tester.checkFile(fileLocation, false, null);
|
||||||
if (reader != null) {
|
if (reader != null) {
|
||||||
return reader;
|
return reader;
|
||||||
}
|
}
|
||||||
|
@ -894,43 +896,31 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
|
|
||||||
// if we're not include_next, then we are looking for the first occurrence of
|
// if we're not include_next, then we are looking for the first occurrence of
|
||||||
// the file, otherwise, we ignore all the paths before the current directory
|
// the file, otherwise, we ignore all the paths before the current directory
|
||||||
final String[] isp= quoteInclude ? fQuoteIncludePaths : fIncludePaths;
|
IncludeSearchPathElement searchAfter= includeNext ? fCurrentContext.getFoundOnPath() : null;
|
||||||
if (isp != null) {
|
for (IncludeSearchPathElement path : fIncludeSearchPath) {
|
||||||
int i=0;
|
if (searchAfter != null) {
|
||||||
if (includeNext && currentFile != null) {
|
if (searchAfter.equals(path)) {
|
||||||
final File currentDir= new File(currentFile).getParentFile();
|
searchAfter= null;
|
||||||
if (currentDir != null) {
|
|
||||||
i= findIncludePos(isp, currentDir) + 1;
|
|
||||||
}
|
}
|
||||||
}
|
} else if (quoteInclude || !path.isForQuoteIncludesOnly()) {
|
||||||
for (; i < isp.length; ++i) {
|
String fileLocation = path.getLocation(includeDirective);
|
||||||
reader= tester.checkFile(isp[i], filename, false);
|
if (fileLocation != null) {
|
||||||
if (reader != null) {
|
reader= tester.checkFile(fileLocation, false, path);
|
||||||
return reader;
|
if (reader != null) {
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fIncludeFileResolutionHeuristics != null) {
|
if (fIncludeFileResolutionHeuristics != null) {
|
||||||
String location= fIncludeFileResolutionHeuristics.findInclusion(filename, currentFile);
|
String location= fIncludeFileResolutionHeuristics.findInclusion(includeDirective, currentFile);
|
||||||
if (location != null) {
|
if (location != null) {
|
||||||
return tester.checkFile(null, location, true);
|
return tester.checkFile(location, true, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private int findIncludePos(String[] paths, File currentDirectory) {
|
|
||||||
for (; currentDirectory != null; currentDirectory = currentDirectory.getParentFile()) {
|
|
||||||
for (int i = 0; i < paths.length; ++i) {
|
|
||||||
File pathDir = new File(paths[i]);
|
|
||||||
if (currentDirectory.equals(pathDir))
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuffer buffer = new StringBuffer("Scanner @ file:"); //$NON-NLS-1$
|
StringBuffer buffer = new StringBuffer("Scanner @ file:"); //$NON-NLS-1$
|
||||||
|
@ -1191,6 +1181,7 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
|
||||||
fAllIncludedFiles.add(path);
|
fAllIncludedFiles.add(path);
|
||||||
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic, fi.isSource());
|
ILocationCtx ctx= fLocationMap.pushInclusion(poundOffset, nameOffsets[0], nameOffsets[1], condEndOffset, reader.buffer, path, headerName, userInclude, isHeuristic, fi.isSource());
|
||||||
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer, fLexOptions, this, this));
|
ScannerContext fctx= new ScannerContext(ctx, fCurrentContext, new Lexer(reader.buffer, fLexOptions, this, this));
|
||||||
|
fctx.setFoundOnPath(fi.getFoundOnPath());
|
||||||
fCurrentContext= fctx;
|
fCurrentContext= fctx;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -46,6 +46,7 @@ public class IncludeFileContent {
|
||||||
private boolean fHeuristic;
|
private boolean fHeuristic;
|
||||||
private boolean fIsSource= false;
|
private boolean fIsSource= false;
|
||||||
private List<IIndexFile> fFiles;
|
private List<IIndexFile> fFiles;
|
||||||
|
private IncludeSearchPathElement fFoundOnPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For skipping include files.
|
* For skipping include files.
|
||||||
|
@ -165,4 +166,12 @@ public class IncludeFileContent {
|
||||||
public void setIsSource(boolean isSource) {
|
public void setIsSource(boolean isSource) {
|
||||||
fIsSource= isSource;
|
fIsSource= isSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public IncludeSearchPathElement getFoundOnPath() {
|
||||||
|
return fFoundOnPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setFoundOnPath(IncludeSearchPathElement isp) {
|
||||||
|
fFoundOnPath= isp;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
/*******************************************************************************
|
||||||
|
* Copyright (c) 2009 Wind River Systems, Inc. and others.
|
||||||
|
* All rights reserved. This program and the accompanying materials
|
||||||
|
* are made available under the terms of the Eclipse Public License v1.0
|
||||||
|
* which accompanies this distribution, and is available at
|
||||||
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
|
*
|
||||||
|
* Contributors:
|
||||||
|
* Markus Schorn - initial API and implementation
|
||||||
|
*******************************************************************************/
|
||||||
|
package org.eclipse.cdt.internal.core.parser.scanner;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents an entry of the include search path
|
||||||
|
*/
|
||||||
|
final class IncludeSearchPathElement {
|
||||||
|
private static final boolean NON_SLASH_SEPARATOR = File.separatorChar != '/';
|
||||||
|
public static final String FRAMEWORK_VAR = "__framework__"; //$NON-NLS-1$
|
||||||
|
public static final String FILE_VAR = "__filename__"; //$NON-NLS-1$
|
||||||
|
|
||||||
|
|
||||||
|
private final String fPath;
|
||||||
|
private final boolean fForQuoteIncludesOnly;
|
||||||
|
private final boolean fIsFrameworkDirectory;
|
||||||
|
|
||||||
|
IncludeSearchPathElement(String path, boolean forQuoteIncludesOnly) {
|
||||||
|
fPath= path;
|
||||||
|
fForQuoteIncludesOnly= forQuoteIncludesOnly;
|
||||||
|
|
||||||
|
if (path.indexOf('_') != -1 && path.indexOf(FRAMEWORK_VAR) != -1 && path.indexOf(FILE_VAR) != -1) {
|
||||||
|
fIsFrameworkDirectory= true;
|
||||||
|
} else {
|
||||||
|
fIsFrameworkDirectory= false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isForQuoteIncludesOnly() {
|
||||||
|
return fForQuoteIncludesOnly;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLocation(String includeDirective) {
|
||||||
|
if (fIsFrameworkDirectory) {
|
||||||
|
int lastSep = lastSeparator(includeDirective);
|
||||||
|
if (lastSep < 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
String framework = includeDirective.substring(0, lastSep);
|
||||||
|
if (lastSeparator(framework) != -1 || framework.length() == 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
String file= includeDirective.substring(lastSep+1);
|
||||||
|
if (file.length() == 0)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
StringBuilder buf= new StringBuilder(fPath);
|
||||||
|
replaceAll(buf, FRAMEWORK_VAR, framework);
|
||||||
|
replaceAll(buf, FILE_VAR, file);
|
||||||
|
return ScannerUtility.reconcilePath(buf.toString());
|
||||||
|
}
|
||||||
|
return ScannerUtility.createReconciledPath(fPath, includeDirective);
|
||||||
|
}
|
||||||
|
|
||||||
|
private int lastSeparator(String path) {
|
||||||
|
int lastSep= path.lastIndexOf('/');
|
||||||
|
if (NON_SLASH_SEPARATOR) {
|
||||||
|
lastSep= Math.max(lastSep, path.lastIndexOf(File.separatorChar));
|
||||||
|
}
|
||||||
|
return lastSep;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void replaceAll(StringBuilder buf, String find, final String replace) {
|
||||||
|
for (int idx= buf.indexOf(find); idx > 0; idx= buf.indexOf(find, idx)) {
|
||||||
|
buf.replace(idx, idx+find.length(), replace);
|
||||||
|
idx+= replace.length();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -44,6 +44,7 @@ final class ScannerContext {
|
||||||
private Token fTokens;
|
private Token fTokens;
|
||||||
private ArrayList<Conditional> fConditionals= null;
|
private ArrayList<Conditional> fConditionals= null;
|
||||||
private CodeState fCurrentState= CodeState.eActive;
|
private CodeState fCurrentState= CodeState.eActive;
|
||||||
|
private IncludeSearchPathElement fFoundOnPath;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param ctx
|
* @param ctx
|
||||||
|
@ -56,9 +57,7 @@ final class ScannerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScannerContext(ILocationCtx ctx, ScannerContext parent, TokenList tokens) {
|
public ScannerContext(ILocationCtx ctx, ScannerContext parent, TokenList tokens) {
|
||||||
fLocationCtx= ctx;
|
this (ctx, parent, (Lexer) null);
|
||||||
fParent= parent;
|
|
||||||
fLexer= null;
|
|
||||||
fTokens= tokens.first();
|
fTokens= tokens.first();
|
||||||
fInactiveState= CodeState.eSkipInactive; // no branches in result of macro expansion
|
fInactiveState= CodeState.eSkipInactive; // no branches in result of macro expansion
|
||||||
}
|
}
|
||||||
|
@ -270,4 +269,18 @@ final class ScannerContext {
|
||||||
return 0;
|
return 0;
|
||||||
return fConditionals.size();
|
return fConditionals.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the element of the include search path that was used to find this context, or <code>null</code> if not applicable.
|
||||||
|
*/
|
||||||
|
public IncludeSearchPathElement getFoundOnPath() {
|
||||||
|
return fFoundOnPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the element of the include search path that was used to find this context, or <code>null</code> if not applicable.
|
||||||
|
*/
|
||||||
|
public void setFoundOnPath(IncludeSearchPathElement foundOnPath) {
|
||||||
|
fFoundOnPath= foundOnPath;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue