1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-29 11:55:40 +02:00

More cleanup

This commit is contained in:
Andrew Gvozdev 2012-03-29 13:54:50 -04:00
parent be44991629
commit e157e1a63e
9 changed files with 218 additions and 157 deletions

View file

@ -58,7 +58,7 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase {
private class MockBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector { private class MockBuiltinSpecsDetector extends AbstractBuiltinSpecsDetector {
@Override @Override
protected List<String> parseForOptions(String line) { protected List<String> parseOptions(String line) {
return null; return null;
} }
@Override @Override
@ -82,7 +82,7 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase {
private class MockBuiltinSpecsDetectorExecutedFlag extends AbstractBuiltinSpecsDetector { private class MockBuiltinSpecsDetectorExecutedFlag extends AbstractBuiltinSpecsDetector {
@Override @Override
protected List<String> parseForOptions(String line) { protected List<String> parseOptions(String line) {
return null; return null;
} }
@Override @Override
@ -120,7 +120,7 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase {
return super.runForEachLanguage(monitor); return super.runForEachLanguage(monitor);
} }
@Override @Override
protected List<String> parseForOptions(final String line) { protected List<String> parseOptions(final String line) {
return new ArrayList<String>() {{ add(line); }}; return new ArrayList<String>() {{ add(line); }};
} }
@Override @Override
@ -140,7 +140,11 @@ public class BuiltinSpecsDetectorTest extends BaseTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
Job.getJobManager().join(AbstractBuiltinSpecsDetector.JOB_FAMILY_BUILTIN_SPECS_DETECTOR, null); try {
Job.getJobManager().join(AbstractBuiltinSpecsDetector.JOB_FAMILY_BUILTIN_SPECS_DETECTOR, null);
} catch (Exception e) {
// ignore
}
super.tearDown(); super.tearDown();
} }

View file

@ -92,7 +92,11 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
@Override @Override
protected void tearDown() throws Exception { protected void tearDown() throws Exception {
Job.getJobManager().join(AbstractBuildCommandParser.JOB_FAMILY_BUILD_COMMAND_PARSER, null); try {
Job.getJobManager().join(AbstractBuildCommandParser.JOB_FAMILY_BUILD_COMMAND_PARSER, null);
} catch (Exception e) {
// ignore
}
super.tearDown(); super.tearDown();
} }
@ -1745,7 +1749,7 @@ public class GCCBuildCommandParserTest extends BaseTestCase {
public void testContentType_None() throws Exception { public void testContentType_None() throws Exception {
MockBuildCommandParser parser = new MockBuildCommandParser() { MockBuildCommandParser parser = new MockBuildCommandParser() {
@Override @Override
protected String parseForResourceName(String line) { protected String parseResourceName(String line) {
return "file.wrong-content-type"; return "file.wrong-content-type";
} }
}; };

View file

@ -12,10 +12,14 @@
package org.eclipse.cdt.make.core.language.settings.providers; package org.eclipse.cdt.make.core.language.settings.providers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.IErrorParser2; import org.eclipse.cdt.core.IErrorParser2;
import org.eclipse.cdt.core.IMarkerGenerator; import org.eclipse.cdt.core.IMarkerGenerator;
import org.eclipse.cdt.core.errorparsers.RegexErrorParser; import org.eclipse.cdt.core.errorparsers.RegexErrorParser;
@ -28,6 +32,9 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.eclipse.core.runtime.jobs.ISchedulingRule; import org.eclipse.core.runtime.jobs.ISchedulingRule;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
@ -96,9 +103,42 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting
return pattern; return pattern;
} }
@SuppressWarnings("nls")
private static String expressionLogicalOr(Set<String> fileExts) {
String pattern = "(";
for (String ext : fileExts) {
if (pattern.length() != 1)
pattern += "|";
pattern += "(" + Pattern.quote(ext) + ")";
ext = ext.toUpperCase();
if (!fileExts.contains(ext)) {
pattern += "|(" + Pattern.quote(ext) + ")";
}
}
pattern += ")";
return pattern;
}
protected String getPatternFileExtensions() {
IContentTypeManager manager = Platform.getContentTypeManager();
Set<String> fileExts = new HashSet<String>();
IContentType contentTypeCpp = manager.getContentType(CCorePlugin.CONTENT_TYPE_CXXSOURCE);
fileExts.addAll(Arrays.asList(contentTypeCpp.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)));
IContentType contentTypeC = manager.getContentType(CCorePlugin.CONTENT_TYPE_CSOURCE);
fileExts.addAll(Arrays.asList(contentTypeC.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)));
String pattern = expressionLogicalOr(fileExts);
return pattern;
}
@Override @Override
protected String parseForResourceName(String line) { protected String parseResourceName(String line) {
if (line==null) { if (line == null) {
return null; return null;
} }
@ -115,8 +155,8 @@ public abstract class AbstractBuildCommandParser extends AbstractLanguageSetting
} }
@Override @Override
protected List<String> parseForOptions(String line) { protected List<String> parseOptions(String line) {
if (line==null || currentResource==null) { if (line == null || currentResource == null) {
return null; return null;
} }

View file

@ -264,7 +264,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
* TODO * TODO
*/ */
@Override @Override
protected String parseForResourceName(String line) { protected String parseResourceName(String line) {
// Returning null works as if workspace-wide // Returning null works as if workspace-wide
return null; return null;
} }
@ -319,10 +319,7 @@ public abstract class AbstractBuiltinSpecsDetector extends AbstractLanguageSetti
mappedRootURI = null; mappedRootURI = null;
buildDirURI = null; buildDirURI = null;
ICConfigurationDescription cfgDescription = currentCfgDescription;
super.shutdown(); super.shutdown();
// keep currentCfgDescription, do not let super.shutdown() to clear it
currentCfgDescription = cfgDescription;
} }
protected void execute() { protected void execute() {

View file

@ -16,8 +16,6 @@ import java.io.IOException;
import java.net.URI; import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@ -26,6 +24,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.ErrorParserManager;
import org.eclipse.cdt.core.cdtvariables.CdtVariableException; import org.eclipse.cdt.core.cdtvariables.CdtVariableException;
import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager; import org.eclipse.cdt.core.cdtvariables.ICdtVariableManager;
import org.eclipse.cdt.core.language.settings.providers.ICBuildOutputParser; import org.eclipse.cdt.core.language.settings.providers.ICBuildOutputParser;
@ -50,9 +49,6 @@ import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.content.IContentTypeManager;
import org.w3c.dom.Element; import org.w3c.dom.Element;
/** /**
@ -61,7 +57,6 @@ import org.w3c.dom.Element;
* @since 7.2 * @since 7.2
*/ */
public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSettingsSerializableProvider implements ICBuildOutputParser { public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSettingsSerializableProvider implements ICBuildOutputParser {
protected static final String ATTR_KEEP_RELATIVE_PATHS = "keep-relative-paths"; //$NON-NLS-1$ protected static final String ATTR_KEEP_RELATIVE_PATHS = "keep-relative-paths"; //$NON-NLS-1$
protected ICConfigurationDescription currentCfgDescription = null; protected ICConfigurationDescription currentCfgDescription = null;
@ -197,18 +192,18 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
* or "applicable to any resource". By default "no resource found" is used in this * or "applicable to any resource". By default "no resource found" is used in this
* abstract class but extenders can handle otherwise. * abstract class but extenders can handle otherwise.
*/ */
protected abstract String parseForResourceName(String line); protected abstract String parseResourceName(String line);
/** /**
* Parse the line returning the list of substrings to be treated each as input to * Parse the line returning the list of substrings to be treated each as input to
* the option parsers. It is assumed that each substring presents one * the option parsers. It is assumed that each substring presents one
* {@link ICLanguageSettingEntry} (for example compiler options {@code -I/path} or * {@link ICLanguageSettingEntry} (for example compiler options {@code -I/path} or
* {@code -DMACRO=1}. * {@code -DMACRO=1}).
* *
* @param line - one input line from the output stripped from end of line characters. * @param line - one input line from the output stripped from end of line characters.
* @return list of substrings representing language settings entries. * @return list of substrings representing language settings entries.
*/ */
protected abstract List<String> parseForOptions(String line); protected abstract List<String> parseOptions(String line);
/** /**
* @return array of option parsers defining how to parse a string to * @return array of option parsers defining how to parse a string to
@ -228,36 +223,35 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
@Override @Override
public void startup(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker) throws CoreException { public void startup(ICConfigurationDescription cfgDescription, IWorkingDirectoryTracker cwdTracker) throws CoreException {
this.cwdTracker = cwdTracker;
this.currentCfgDescription = cfgDescription; this.currentCfgDescription = cfgDescription;
this.currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null; this.currentProject = cfgDescription != null ? cfgDescription.getProjectDescription().getProject() : null;
this.cwdTracker = cwdTracker;
} }
@Override @Override
public void shutdown() { public void shutdown() {
// release resources for garbage collector // release resources for garbage collector
currentCfgDescription = null; // but keep currentCfgDescription for AbstractBuiltinSpecsDetector flow
currentProject = null;
currentResource = null;
currentLanguageId = null;
cwdTracker = null;
parsedResourceName = null; parsedResourceName = null;
currentLanguageId = null;
currentResource = null;
cwdTracker = null;
} }
@Override @Override
public boolean processLine(String line) { public boolean processLine(String line) {
parsedResourceName = parseForResourceName(line); parsedResourceName = parseResourceName(line);
currentResource = findResource(parsedResourceName); currentResource = findResource(parsedResourceName);
currentLanguageId = determineLanguage(); currentLanguageId = determineLanguage();
if (!isLanguageInScope(currentLanguageId)) if (!isLanguageInScope(currentLanguageId)) {
return false; return false;
}
/** /**
* URI of directory where the build is happening. This URI could point to a remote filesystem * URI of directory where the build is happening. This URI could point to a remote file-system
* for remote builds. Most often it is the same filesystem as for currentResource but * for remote builds. Most often it is the same file-system as for currentResource but
* it can be different filesystem (and different URI schema). * it can be different file-system (and different URI schema).
*/ */
URI buildDirURI = null; URI buildDirURI = null;
@ -265,7 +259,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
* Where source tree starts if mapped. This kind of mapping is useful for example in cases when * Where source tree starts if mapped. This kind of mapping is useful for example in cases when
* the absolute path to the source file on the remote system is simulated inside a project in the * the absolute path to the source file on the remote system is simulated inside a project in the
* workspace. * workspace.
* This URI is rooted on the same filesystem where currentResource resides. In general this filesystem * This URI is rooted on the same file-system where currentResource resides. In general this file-system
* (or even URI schema) does not have to match that of buildDirURI. * (or even URI schema) does not have to match that of buildDirURI.
*/ */
URI mappedRootURI = null; URI mappedRootURI = null;
@ -277,17 +271,18 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>(); List<ICLanguageSettingEntry> entries = new ArrayList<ICLanguageSettingEntry>();
List<String> options = parseForOptions(line); List<String> options = parseOptions(line);
if (options!=null) { if (options != null) {
for (String option : options) { for (String option : options) {
@SuppressWarnings("unused")
int i =0;
for (AbstractOptionParser optionParser : getOptionParsers()) { for (AbstractOptionParser optionParser : getOptionParsers()) {
try { try {
if (optionParser.parseOption(option)) { if (optionParser.parseOption(option)) {
ICLanguageSettingEntry entry = null; ICLanguageSettingEntry entry = null;
if (isResolvingPaths && optionParser.isPathKind()) { if (isResolvingPaths && optionParser.isPathKind()) {
URI baseURI = new Path(optionParser.parsedName).isAbsolute() ? mappedRootURI : buildDirURI; URI baseURI = mappedRootURI;
if (!new Path(optionParser.parsedName).isAbsolute() && buildDirURI != null) {
baseURI = EFSExtensionManager.getDefault().append(mappedRootURI, buildDirURI.getPath());
}
entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI); entry = createResolvedPathEntry(optionParser, optionParser.parsedName, 0, baseURI);
} else { } else {
entry = optionParser.createEntry(optionParser.parsedName, optionParser.parsedValue, 0); entry = optionParser.createEntry(optionParser.parsedName, optionParser.parsedValue, 0);
@ -313,7 +308,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return false; return false;
} }
// TODO - remove me // TODO - temporary, remove me
@Deprecated @Deprecated
protected String getPrefixForLog() { protected String getPrefixForLog() {
String str; String str;
@ -334,12 +329,17 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
+ getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + currentResource); + getClass().getSimpleName() + " collected " + (entries!=null ? ("" + entries.size()) : "null") + " entries for " + currentResource);
} }
/**
* Determine a language associated with the resource.
*
* @return language ID for the resource.
*/
protected String determineLanguage() { protected String determineLanguage() {
IResource rc = currentResource; IResource rc = currentResource;
if (rc == null && currentProject != null && parsedResourceName != null) { if (rc == null && currentProject != null && parsedResourceName != null) {
String fileName = new Path(parsedResourceName).lastSegment().toString(); String fileName = new Path(parsedResourceName).lastSegment().toString();
// use handle; resource does not need to exist // use handle; resource does not need to exist
rc = currentProject.getFile("__" + fileName); rc = currentProject.getFile("__" + fileName); //$NON-NLS-1$
} }
if (rc == null) if (rc == null)
@ -352,31 +352,23 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return languageIds.get(0); return languageIds.get(0);
} }
/**
* Determine if the language is in scope of the provider.
*
* @param languageId - language ID.
* @return {@code true} if the language is in scope, {@code false } otherwise.
*/
protected boolean isLanguageInScope(String languageId) { protected boolean isLanguageInScope(String languageId) {
List<String> languageIds = getLanguageScope(); List<String> languageIds = getLanguageScope();
return languageIds == null || languageIds.contains(languageId); return languageIds == null || languageIds.contains(languageId);
} }
protected String getPatternFileExtensions() { /**
IContentTypeManager manager = Platform.getContentTypeManager(); * Resolve and create language settings path entry.
*/
Set<String> fileExts = new HashSet<String>();
IContentType contentTypeCpp = manager.getContentType("org.eclipse.cdt.core.cxxSource");
fileExts.addAll(Arrays.asList(contentTypeCpp.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)));
IContentType contentTypeC = manager.getContentType("org.eclipse.cdt.core.cSource");
fileExts.addAll(Arrays.asList(contentTypeC.getFileSpecs(IContentType.FILE_EXTENSION_SPEC)));
String pattern = expressionLogicalOr(fileExts);
return pattern;
}
private ICLanguageSettingEntry createResolvedPathEntry(AbstractOptionParser optionParser, private ICLanguageSettingEntry createResolvedPathEntry(AbstractOptionParser optionParser,
String parsedPath, int flag, URI baseURI) { String parsedPath, int flag, URI baseURI) {
ICLanguageSettingEntry entry;
String resolvedPath = null; String resolvedPath = null;
URI uri = determineMappedURI(parsedPath, baseURI); URI uri = determineMappedURI(parsedPath, baseURI);
@ -415,25 +407,39 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
resolvedPath = parsedPath; resolvedPath = parsedPath;
} }
entry = optionParser.createEntry(resolvedPath, resolvedPath, flag); return optionParser.createEntry(resolvedPath, resolvedPath, flag);
return entry;
} }
/**
* Determine resource in the workspace corresponding to the parsed resource name.
*/
private IResource findResource(String parsedResourceName) { private IResource findResource(String parsedResourceName) {
if (parsedResourceName == null) if (parsedResourceName == null || parsedResourceName.isEmpty()) {
return null; return null;
}
IResource sourceFile = null; IResource sourceFile = null;
// try ErrorParserManager // try ErrorParserManager
if (cwdTracker != null) { if (cwdTracker instanceof ErrorParserManager) {
sourceFile = cwdTracker.findFileName(parsedResourceName); sourceFile = ((ErrorParserManager) cwdTracker).findFileName(parsedResourceName);
} }
// try to find absolute path in the workspace // try to find absolute path in the workspace
if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) { if (sourceFile == null && new Path(parsedResourceName).isAbsolute()) {
URI uri = org.eclipse.core.filesystem.URIUtil.toURI(parsedResourceName); URI uri = org.eclipse.core.filesystem.URIUtil.toURI(parsedResourceName);
sourceFile = findFileForLocationURI(uri, currentProject); sourceFile = findFileForLocationURI(uri, currentProject);
} }
// try last known current working directory from build output
if (sourceFile == null && cwdTracker != null) {
URI cwdURI = cwdTracker.getWorkingDirectoryURI();
if (cwdURI != null) {
URI uri = EFSExtensionManager.getDefault().append(cwdURI, parsedResourceName);
sourceFile = findFileForLocationURI(uri, currentProject);
}
}
// try path relative to build dir from configuration // try path relative to build dir from configuration
if (sourceFile == null && currentCfgDescription != null) { if (sourceFile == null && currentCfgDescription != null) {
IPath builderCWD = currentCfgDescription.getBuildSetting().getBuilderCWD(); IPath builderCWD = currentCfgDescription.getBuildSetting().getBuilderCWD();
@ -443,24 +449,30 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
sourceFile = findFileForLocationURI(uri, currentProject); sourceFile = findFileForLocationURI(uri, currentProject);
} }
} }
// try path relative to the project // try path relative to the project
if (sourceFile == null && currentProject != null) { if (sourceFile == null && currentProject != null) {
sourceFile = currentProject.findMember(parsedResourceName); sourceFile = currentProject.findMember(parsedResourceName);
} }
return sourceFile; return sourceFile;
} }
/**
* Determine current build directory considering currentResource (resource being compiled),
* parsedResourceName and mappedRootURI.
*
* @param mappedRootURI - root of the source tree when mapped to remote file-system.
* @return {@link URI} of current build directory
*/
protected URI getBuildDirURI(URI mappedRootURI) { protected URI getBuildDirURI(URI mappedRootURI) {
URI buildDirURI = null; URI buildDirURI = null;
// try to deduce build directory from full path of currentResource and partial path of parsedResourceName
URI cwdURI = null; URI cwdURI = null;
if (currentResource!=null && parsedResourceName!=null && !new Path(parsedResourceName).isAbsolute()) { if (currentResource != null && parsedResourceName != null && !new Path(parsedResourceName).isAbsolute()) {
cwdURI = findBaseLocationURI(currentResource.getLocationURI(), parsedResourceName); cwdURI = findBaseLocationURI(currentResource.getLocationURI(), parsedResourceName);
} }
if (cwdURI == null && cwdTracker != null) {
cwdURI = cwdTracker.getWorkingDirectoryURI();
}
String cwdPath = cwdURI != null ? EFSExtensionManager.getDefault().getPathFromURI(cwdURI) : null; String cwdPath = cwdURI != null ? EFSExtensionManager.getDefault().getPathFromURI(cwdURI) : null;
if (cwdPath != null && mappedRootURI != null) { if (cwdPath != null && mappedRootURI != null) {
buildDirURI = EFSExtensionManager.getDefault().append(mappedRootURI, cwdPath); buildDirURI = EFSExtensionManager.getDefault().append(mappedRootURI, cwdPath);
@ -468,14 +480,21 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
buildDirURI = cwdURI; buildDirURI = cwdURI;
} }
// if not found - try IWorkingDirectoryTracker
if (buildDirURI == null && cwdTracker != null) {
buildDirURI = cwdTracker.getWorkingDirectoryURI();
}
// if not found - try builder working directory
if (buildDirURI == null && currentCfgDescription != null) { if (buildDirURI == null && currentCfgDescription != null) {
IPath pathBuilderCWD = currentCfgDescription.getBuildSetting().getBuilderCWD(); IPath pathBuilderCWD = currentCfgDescription.getBuildSetting().getBuilderCWD();
if (pathBuilderCWD != null) { if (pathBuilderCWD != null) {
String builderCWD = pathBuilderCWD.toString(); String builderCWD = pathBuilderCWD.toString();
try { try {
// TODO - here is a hack to overcome ${workspace_loc:/prj-name} returned by builder // here is a hack to overcome ${workspace_loc:/prj-name} returned by builder
// where "/" is treated as path separator by pathBuilderCWD
ICdtVariableManager vmanager = CCorePlugin.getDefault().getCdtVariableManager(); ICdtVariableManager vmanager = CCorePlugin.getDefault().getCdtVariableManager();
builderCWD = vmanager.resolveValue(builderCWD, "", null, currentCfgDescription); builderCWD = vmanager.resolveValue(builderCWD, "", null, currentCfgDescription); //$NON-NLS-1$
} catch (CdtVariableException e) { } catch (CdtVariableException e) {
MakeCorePlugin.log(e); MakeCorePlugin.log(e);
} }
@ -483,10 +502,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} }
} }
// if not found - try directory of the current project
if (buildDirURI == null && currentProject != null) { if (buildDirURI == null && currentProject != null) {
buildDirURI = currentProject.getLocationURI(); buildDirURI = currentProject.getLocationURI();
} }
// if not found - try parent folder of the resource
if (buildDirURI == null && currentResource != null) { if (buildDirURI == null && currentResource != null) {
IContainer container; IContainer container;
if (currentResource instanceof IContainer) { if (currentResource instanceof IContainer) {
@ -500,7 +521,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} }
/** /**
* Determine URI on the local filesystem considering possible mapping. * Determine URI on the local file-system considering possible mapping.
* *
* @param pathStr - path to the resource, can be absolute or relative * @param pathStr - path to the resource, can be absolute or relative
* @param baseURI - base {@link URI} where path to the resource is rooted * @param baseURI - base {@link URI} where path to the resource is rooted
@ -509,22 +530,22 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
private static URI determineMappedURI(String pathStr, URI baseURI) { private static URI determineMappedURI(String pathStr, URI baseURI) {
URI uri = null; URI uri = null;
if (baseURI==null) { if (baseURI == null) {
if (new Path(pathStr).isAbsolute()) { if (new Path(pathStr).isAbsolute()) {
uri = resolvePathFromBaseLocation(pathStr, Path.ROOT); uri = resolvePathFromBaseLocation(pathStr, Path.ROOT);
} }
} else if (baseURI.getScheme().equals(EFS.SCHEME_FILE)) { } else if (baseURI.getScheme().equals(EFS.SCHEME_FILE)) {
// location on the local filesystem // location on the local file-system
IPath baseLocation = org.eclipse.core.filesystem.URIUtil.toPath(baseURI); IPath baseLocation = org.eclipse.core.filesystem.URIUtil.toPath(baseURI);
// careful not to use Path here but 'pathStr' as String as we want to properly navigate symlinks // careful not to use Path here but 'pathStr' as String as we want to properly navigate symlinks
uri = resolvePathFromBaseLocation(pathStr, baseLocation); uri = resolvePathFromBaseLocation(pathStr, baseLocation);
} else { } else {
// location on a remote filesystem // location on a remote file-system
IPath path = new Path(pathStr); // use canonicalized path here, in particular replace all '\' with '/' for Windows paths IPath path = new Path(pathStr); // use canonicalized path here, in particular replace all '\' with '/' for Windows paths
URI remoteUri = EFSExtensionManager.getDefault().append(baseURI, path.toString()); URI remoteUri = EFSExtensionManager.getDefault().append(baseURI, path.toString());
if (remoteUri!=null) { if (remoteUri != null) {
String localPath = EFSExtensionManager.getDefault().getMappedPath(remoteUri); String localPath = EFSExtensionManager.getDefault().getMappedPath(remoteUri);
if (localPath!=null) { if (localPath != null) {
uri = org.eclipse.core.filesystem.URIUtil.toURI(localPath); uri = org.eclipse.core.filesystem.URIUtil.toURI(localPath);
} }
} }
@ -537,6 +558,9 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return uri; return uri;
} }
/**
* Determine which resource in workspace is the best fit to parsedName passed.
*/
private static IResource resolveResourceInWorkspace(String parsedName, IProject preferredProject, Set<String> referencedProjectsNames) { private static IResource resolveResourceInWorkspace(String parsedName, IProject preferredProject, Set<String> referencedProjectsNames) {
IPath path = new Path(parsedName); IPath path = new Path(parsedName);
if (path.equals(new Path(".")) || path.equals(new Path(".."))) { //$NON-NLS-1$ //$NON-NLS-2$ if (path.equals(new Path(".")) || path.equals(new Path(".."))) { //$NON-NLS-1$ //$NON-NLS-2$
@ -544,12 +568,12 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} }
// prefer current project // prefer current project
if (preferredProject!=null) { if (preferredProject != null) {
List<IResource> result = findPathInFolder(path, preferredProject); List<IResource> result = findPathInFolder(path, preferredProject);
int size = result.size(); int size = result.size();
if (size==1) { // found the one if (size == 1) { // found the one
return result.get(0); return result.get(0);
} else if (size>1) { // ambiguous } else if (size > 1) { // ambiguous
return null; return null;
} }
} }
@ -564,7 +588,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
if (prj.isOpen()) { if (prj.isOpen()) {
List<IResource> result = findPathInFolder(path, prj); List<IResource> result = findPathInFolder(path, prj);
int size = result.size(); int size = result.size();
if (size==1 && rc==null) { if (size == 1 && rc == null) {
rc = result.get(0); rc = result.get(0);
} else if (size > 0) { } else if (size > 0) {
// ambiguous // ambiguous
@ -586,7 +610,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
if (!prj.equals(preferredProject) && !referencedProjectsNames.contains(prj.getName()) && prj.isOpen()) { if (!prj.equals(preferredProject) && !referencedProjectsNames.contains(prj.getName()) && prj.isOpen()) {
List<IResource> result = findPathInFolder(path, prj); List<IResource> result = findPathInFolder(path, prj);
int size = result.size(); int size = result.size();
if (size==1 && rc==null) { if (size == 1 && rc == null) {
rc = result.get(0); rc = result.get(0);
} else if (size > 0) { } else if (size > 0) {
// ambiguous // ambiguous
@ -595,7 +619,7 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
} }
} }
} }
if (rc!=null) { if (rc != null) {
return rc; return rc;
} }
} }
@ -604,6 +628,9 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return null; return null;
} }
/**
* Find all resources in the folder which might be represented by relative path passed.
*/
private static List<IResource> findPathInFolder(IPath path, IContainer folder) { private static List<IResource> findPathInFolder(IPath path, IContainer folder) {
List<IResource> paths = new ArrayList<IResource>(); List<IResource> paths = new ArrayList<IResource>();
IResource resource = folder.findMember(path); IResource resource = folder.findMember(path);
@ -624,26 +651,33 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return paths; return paths;
} }
/**
* Find resource in the workspace for a given URI with a preference for the resource
* to reside in the given project.
*/
private static IResource findFileForLocationURI(URI uri, IProject preferredProject) { private static IResource findFileForLocationURI(URI uri, IProject preferredProject) {
IResource sourceFile; IResource sourceFile = null;
IResource result = null;
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
IResource[] resources = root.findFilesForLocationURI(uri); IResource[] resources = root.findFilesForLocationURI(uri);
if (resources.length > 0) { if (resources.length > 0) {
result = resources[0]; sourceFile = resources[0];
if (preferredProject!=null) { if (preferredProject != null) {
for (IResource rc : resources) { for (IResource rc : resources) {
if (rc.getProject().equals(preferredProject)) { if (rc.getProject().equals(preferredProject)) {
result = rc; sourceFile = rc;
break; break;
} }
} }
} }
} }
sourceFile = result;
return sourceFile; return sourceFile;
} }
/**
* Find base location of the file, i.e. location of the directory which
* results from removing trailing relativeFileName from fileURI or
* {@code null} if fileURI doesn't represent relativeFileName.
*/
private static URI findBaseLocationURI(URI fileURI, String relativeFileName) { private static URI findBaseLocationURI(URI fileURI, String relativeFileName) {
URI cwdURI = null; URI cwdURI = null;
String path = fileURI.getPath(); String path = fileURI.getPath();
@ -687,40 +721,44 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
* i.e URI where the root path would be mapped. The mapped root will be * i.e URI where the root path would be mapped. The mapped root will be
* used to prepend to other "absolute" paths where appropriate. * used to prepend to other "absolute" paths where appropriate.
* *
* @param sourceFile - a resource referred by parsed path * @param resource - a resource referred by parsed path
* @param parsedResourceName - path as appears in the output * @param parsedResourceName - path as appears in the output
* @return mapped path as URI * @return mapped path as URI
*/ */
protected URI getMappedRootURI(IResource sourceFile, String parsedResourceName) { protected URI getMappedRootURI(IResource resource, String parsedResourceName) {
if (currentResource==null) { if (resource == null) {
return null; return null;
} }
URI fileURI = sourceFile.getLocationURI(); URI resourceURI = resource.getLocationURI();
String mappedRoot = "/"; //$NON-NLS-1$ String mappedRoot = "/"; //$NON-NLS-1$
if (parsedResourceName!=null) { if (parsedResourceName != null) {
IPath parsedSrcPath = new Path(parsedResourceName); IPath parsedSrcPath = new Path(parsedResourceName);
if (parsedSrcPath.isAbsolute()) { if (parsedSrcPath.isAbsolute()) {
IPath absPath = sourceFile.getLocation(); IPath absResourcePath = resource.getLocation();
int absSegmentsCount = absPath.segmentCount(); int absSegmentsCount = absResourcePath.segmentCount();
int relSegmentsCount = parsedSrcPath.segmentCount(); int relSegmentsCount = parsedSrcPath.segmentCount();
if (absSegmentsCount >= relSegmentsCount) { if (absSegmentsCount >= relSegmentsCount) {
IPath ending = absPath.removeFirstSegments(absSegmentsCount - relSegmentsCount); IPath ending = absResourcePath.removeFirstSegments(absSegmentsCount - relSegmentsCount);
ending = ending.setDevice(parsedSrcPath.getDevice()).makeAbsolute(); ending = ending.setDevice(parsedSrcPath.getDevice()).makeAbsolute();
if (ending.equals(parsedSrcPath.makeAbsolute())) { if (ending.equals(parsedSrcPath.makeAbsolute())) {
mappedRoot = absPath.removeLastSegments(relSegmentsCount).toString(); // mappedRoot here is parsedSrcPath with removed parsedResourceName trailing segments,
// i.e. if absResourcePath="/path/workspace/project/file.c" and parsedResourceName="project/file.c"
// then mappedRoot="/path/workspace/"
mappedRoot = absResourcePath.removeLastSegments(relSegmentsCount).toString();
} }
} }
} }
} }
URI uri = EFSExtensionManager.getDefault().createNewURIFromPath(fileURI, mappedRoot); // this creates URI with schema and other components from resourceURI but path as mappedRoot
URI uri = EFSExtensionManager.getDefault().createNewURIFromPath(resourceURI, mappedRoot);
return uri; return uri;
} }
/** /**
* The manipulations here are done to resolve "../" navigation for symbolic links where "link/.." cannot * The manipulations here are done to resolve "../" navigation for symbolic links where "link/.." cannot
* be collapsed as it must follow the real filesystem path. {@link java.io.File#getCanonicalPath()} deals * be collapsed as it must follow the real file-system path. {@link java.io.File#getCanonicalPath()} deals
* with that correctly but {@link Path} or {@link URI} try to normalize the path which would be incorrect * with that correctly but {@link Path} or {@link URI} try to normalize the path which would be incorrect
* here. * here.
*/ */
@ -750,12 +788,15 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
// if error just leave it as is // if error just leave it as is
} }
URI uri = org.eclipse.core.filesystem.URIUtil.toURI(pathName); return org.eclipse.core.filesystem.URIUtil.toURI(pathName);
return uri;
} }
/**
* Return a resource in workspace corresponding the given {@link URI} preferable residing in
* the provided project.
*/
private static IResource findResourceForLocationURI(URI uri, int kind, IProject preferredProject) { private static IResource findResourceForLocationURI(URI uri, int kind, IProject preferredProject) {
if (uri==null) if (uri == null)
return null; return null;
IResource resource = null; IResource resource = null;
@ -774,32 +815,34 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return resource; return resource;
} }
/**
* Return a resource in workspace corresponding the given folder {@link URI} preferable residing in
* the provided project.
*/
private static IResource findContainerForLocationURI(URI uri, IProject preferredProject) { private static IResource findContainerForLocationURI(URI uri, IProject preferredProject) {
IResource resource = null; IResource resource = null;
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); IResource[] resources = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(uri);
IResource[] resources = root.findContainersForLocationURI(uri); for (IResource rc : resources) {
if (resources.length > 0) { if ((rc instanceof IProject || rc instanceof IFolder)) { // treat IWorkspaceRoot as non-workspace path
for (IResource rc : resources) { if (rc.getProject().equals(preferredProject)) {
if ((rc instanceof IProject || rc instanceof IFolder)) { // treat IWorkspaceRoot as non-workspace path resource = rc;
IProject prj = rc instanceof IProject ? (IProject)rc : rc.getProject(); break;
if (prj.equals(preferredProject)) { }
resource = rc; if (resource == null) {
break; resource = rc; // to be deterministic the first qualified resource has preference
}
if (resource==null) {
resource=rc; // to be deterministic the first qualified resource has preference
}
} }
} }
} }
return resource; return resource;
} }
/**
* Get location on the local file-system considering possible mapping by {@link EFSExtensionManager}.
*/
private static IPath getFilesystemLocation(URI uri) { private static IPath getFilesystemLocation(URI uri) {
if (uri==null) if (uri == null)
return null; return null;
// EFSExtensionManager mapping
String pathStr = EFSExtensionManager.getDefault().getMappedPath(uri); String pathStr = EFSExtensionManager.getDefault().getMappedPath(uri);
uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr); uri = org.eclipse.core.filesystem.URIUtil.toURI(pathStr);
@ -813,22 +856,6 @@ public abstract class AbstractLanguageSettingsOutputScanner extends LanguageSett
return null; return null;
} }
@SuppressWarnings("nls")
private static String expressionLogicalOr(Set<String> fileExts) {
String pattern = "(";
for (String ext : fileExts) {
if (pattern.length() != 1)
pattern += "|";
pattern += "(" + Pattern.quote(ext) + ")";
ext = ext.toUpperCase();
if (!fileExts.contains(ext)) {
pattern += "|(" + Pattern.quote(ext) + ")";
}
}
pattern += ")";
return pattern;
}
protected static int countGroups(String str) { protected static int countGroups(String str) {
@SuppressWarnings("nls") @SuppressWarnings("nls")
int count = str.replaceAll("[^\\(]", "").length(); int count = str.replaceAll("[^\\(]", "").length();

View file

@ -57,7 +57,7 @@ public class GCCBuiltinSpecsDetector extends ToolchainBuiltinSpecsDetector imple
} }
@Override @Override
protected List<String> parseForOptions(String line) { protected List<String> parseOptions(String line) {
line = line.trim(); line = line.trim();
// contribution of -dD option // contribution of -dD option

View file

@ -12,29 +12,17 @@ package org.eclipse.cdt.core.language.settings.providers;
import java.net.URI; import java.net.URI;
import org.eclipse.core.resources.IFile;
/** /**
* TODO * Interface for console parsers able to track current working directory for build.
*
* @since 5.4 * @since 5.4
*/ */
public interface IWorkingDirectoryTracker { public interface IWorkingDirectoryTracker {
// TODO - define the API /**
* Returns current working directory for the current build command as determined from
public URI getWorkingDirectoryURI(); * build output.
public IFile findFileName(String partialLoc); *
* @return URI of current working directory or {@code null}.
/*
public URI findFileURI(String partialLoc);
public URI findFolderURI(String partialLoc);
or
public File findFile(String partialLoc); // best choice
public Folder findFolder(String partialLoc); // best choice
or
public List<URI> findFileURI(String partialLoc); // all candidates
public List<URI> findFolderURI(String partialLoc); // all candidates
*/ */
public URI getWorkingDirectoryURI();
} }

View file

@ -194,6 +194,7 @@ public class ErrorParserManager extends OutputStream implements IConsoleParser,
* @return the current URI location where the build is being performed * @return the current URI location where the build is being performed
* @since 5.1 * @since 5.1
*/ */
@Override
public URI getWorkingDirectoryURI() { public URI getWorkingDirectoryURI() {
if (!fDirectoryStack.isEmpty()) if (!fDirectoryStack.isEmpty())
return fDirectoryStack.lastElement(); return fDirectoryStack.lastElement();

View file

@ -64,7 +64,7 @@ public class XlcBuiltinSpecsDetector extends ToolchainBuiltinSpecsDetector imple
} }
@Override @Override
protected List<String> parseForOptions(String line) { protected List<String> parseOptions(String line) {
List<String> options = new ArrayList<String>(); List<String> options = new ArrayList<String>();
Matcher optionMatcher = OPTIONS_PATTERN.matcher(line); Matcher optionMatcher = OPTIONS_PATTERN.matcher(line);
while (optionMatcher.find()) { while (optionMatcher.find()) {