diff --git a/core/org.eclipse.cdt.core/ChangeLog b/core/org.eclipse.cdt.core/ChangeLog index a25e93da1ae..5af0c6da467 100644 --- a/core/org.eclipse.cdt.core/ChangeLog +++ b/core/org.eclipse.cdt.core/ChangeLog @@ -1,3 +1,19 @@ +2005-03-30 Alain Magloire + PR 88858 implementation. + * model/org/eclipse/cdt/core/model/CoreModel.java + * model/org/eclipse/cdt/core/model/IIncludeFileEntry.java + * model/org/eclipse/cdt/core/model/IMacroFileEntry.java + * model/org/eclipse/cdt/core/model/IPathEntry.java + * model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java + * model/org/eclipse/cdt/internal/core/model/DefaultPathEntryStore.java + * model/org/eclipse/cdt/internal/core/model/IncludeFileEntry.java + * model/org/eclipse/cdt/internal/core/model/MacroFileEntry.java + * model/org/eclipse/cdt/internal/core/model/PathEntry.java + * model/org/eclipse/cdt/internal/core/model/PathEntryManager.java + * model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java + * src/org/eclipse/cdt/core/resources/ScannerInfo.java + * src/org/eclipse/cdt/core/resources/ScannerProvider.java + 2005-03-30 Vladimir Hirsl Fix for NPE in IndexEncoderUtil.calculateIndexFlags diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java index fcbdc2174ae..02abda16d57 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/CoreModel.java @@ -22,8 +22,10 @@ import org.eclipse.cdt.internal.core.model.CModel; import org.eclipse.cdt.internal.core.model.CModelManager; import org.eclipse.cdt.internal.core.model.ContainerEntry; import org.eclipse.cdt.internal.core.model.IncludeEntry; +import org.eclipse.cdt.internal.core.model.IncludeFileEntry; import org.eclipse.cdt.internal.core.model.LibraryEntry; import org.eclipse.cdt.internal.core.model.MacroEntry; +import org.eclipse.cdt.internal.core.model.MacroFileEntry; import org.eclipse.cdt.internal.core.model.OutputEntry; import org.eclipse.cdt.internal.core.model.PathEntryManager; import org.eclipse.cdt.internal.core.model.ProjectEntry; @@ -530,6 +532,37 @@ public class CoreModel { return new IncludeEntry(resourcePath, null, baseRef, includePath, false, null, false); } + /** + * Creates a new entry of kind CDT_INCLUDE_FILE + * + * @param resourcePath + * @param includeFile + * @return + */ + public static IIncludeFileEntry newIncludeFileEntry(IPath resourcePath, IPath includeFile) { + return newIncludeFileEntry(resourcePath, null, null, includeFile, null, false); + } + + /** + * Creates and returns a new entry of kind CDT_INCLUDE_FILE + * + * @param resourcePath + * the affected project-relative resource path + * @param basePath + * the base path of the include + * @param includeFilePath + * the path of the include + * @param exclusionPatterns + * exclusion patterns in the resource if a container + * @param isExported + * if the entry ix exported to reference projects + * @return IIincludeEntry + */ + public static IIncludeFileEntry newIncludeFileEntry(IPath resourcePath, IPath baseRef, IPath basePath, IPath includeFilePath, + IPath[] exclusionPatterns, boolean isExported) { + return new IncludeFileEntry(resourcePath, basePath, baseRef, includeFilePath, exclusionPatterns, isExported); + } + /** * Creates and returns an entry kind CDT_MACRO * @@ -539,7 +572,7 @@ public class CoreModel { * the name of the macro * @param macroValue * the value of the macro - * @return + * @return IMacroEntry */ public static IMacroEntry newMacroEntry(IPath resourcePath, String macroName, String macroValue) { return newMacroEntry(resourcePath, macroName, macroValue, APathEntry.NO_EXCLUSION_PATTERNS); @@ -588,12 +621,41 @@ public class CoreModel { * the base reference path * @param macroName * the name of the macro - * @return + * @return IMacroEntry */ public static IMacroEntry newMacroRefEntry(IPath resourcePath, IPath baseRef, String macroName) { return new MacroEntry(resourcePath, baseRef, macroName, null, APathEntry.NO_EXCLUSION_PATTERNS, false); } + /** + * Creates an entry kind CDT_MACRO_FILE + * + * @param resourcePath + * @param macroFile + * @return + */ + public static IMacroFileEntry newMacroFileEntry(IPath resourcePath, IPath macroFile) { + return newMacroFileEntry(resourcePath, null, null, macroFile, null, false); + } + + /** + * Creates and returns an entry kind CDT_MACRO_FILE + * + * @param resourcePath + * the affected workspace-relative resource path + * @param basePath + * the base path + * @param macroFilePath + * the file path where the macros are define + * @param exclusionPatterns + * exclusion patterns in the resource if a container + * @return + */ + public static IMacroFileEntry newMacroFileEntry(IPath resourcePath, IPath basePath, IPath baseRef, IPath macroFilePath, IPath[] exclusionPatterns, boolean isExported) { + return new MacroFileEntry(resourcePath, basePath, baseRef, macroFilePath, exclusionPatterns, isExported); + } + + /** * Answers the project specific value for a given container. In case this * container path could not be resolved, then will answer null. @@ -741,7 +803,7 @@ public class CoreModel { /** * This method returns the include entries associated with a translation unit - * if the path does not refer to a valid translation unit an empty is return. + * if the path does not refer to a valid translation unit an empty array is return. *

* The resulting resolved entries are accurate for the given point in time. * If the project's raw entries are later modified they can become out of @@ -749,7 +811,7 @@ public class CoreModel { * recommended. *

* - * @return the resolved entries for the project + * @return the include entries for the translation unit * @exception CModelException * @see IPathEntry */ @@ -757,6 +819,24 @@ public class CoreModel { return pathEntryManager.getIncludeEntries(path); } + /** + * This method returns the include file entries associated with a translation unit + * if the path does not refer to a valid translation unit an empty array is return. + *

+ * The resulting resolved entries are accurate for the given point in time. + * If the project's raw entries are later modified they can become out of + * date. Because of this, hanging on resolved pathentries is not + * recommended. + *

+ * + * @return the include file entries for the translation unit + * @exception CModelException + * @see IPathEntry + */ + public static IIncludeFileEntry[] getIncludeFileEntries(IPath path) throws CModelException { + return pathEntryManager.getIncludeFileEntries(path); + } + /** * This method returns the macro entries associated with a translation unit * if the path does not refer to a valid translation unit an empty array is return. @@ -775,6 +855,24 @@ public class CoreModel { return pathEntryManager.getMacroEntries(path); } + /** + * This method returns the macro file entries associated with a translation unit + * if the path does not refer to a valid translation unit an empty array is return. + *

+ * The resulting resolved entries are accurate for the given point in time. + * If the project's raw entries are later modified they can become out of + * date. Because of this, hanging on resolved pathentries is not + * recommended. + *

+ * + * @return the macro file entries for the translation unit + * @exception CModelException + * @see IPathEntry + */ + public static IMacroFileEntry[] getMacroFileEntries(IPath path) throws CModelException { + return pathEntryManager.getMacroFileEntries(path); + } + /** * Helper method finding the pathentry container initializer registered for * a given container ID or null if none was found while diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IIncludeFileEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IIncludeFileEntry.java new file mode 100644 index 00000000000..bcc99ad95f4 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IIncludeFileEntry.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.model; + +import org.eclipse.core.runtime.IPath; + +public interface IIncludeFileEntry extends IPathEntry { + + /** + * Returns the include file + * @return IPath + */ + IPath getIncludeFilePath(); + + /** + * Return the includeFilePath with the base path. + * + * @return + */ + IPath getFullIncludeFilePath(); + + /** + * Return the base path of the includePath + * @return IPath + */ + IPath getBasePath(); + + /** + * Return the reference path + * + * @return + */ + IPath getBaseReference(); + + /** + * If isRecursive() is true, specify an exclude file patterns. + * @return IPath + */ + IPath[] getExclusionPatterns(); + + /** + * Returns a char based representation of the exclusions patterns full path. + */ + public char[][] fullExclusionPatternChars(); + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IMacroFileEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IMacroFileEntry.java new file mode 100644 index 00000000000..350d345b48d --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IMacroFileEntry.java @@ -0,0 +1,53 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.core.model; + +import org.eclipse.core.runtime.IPath; + +public interface IMacroFileEntry extends IPathEntry { + + /** + * Returns the macroFile path. + * @return String + */ + IPath getMacroFilePath(); + + /** + * the path is completed if it relative. + */ + IPath getFullMacroFilePath(); + + /** + * Return the base path. + * @return + */ + IPath getBasePath(); + + /** + * return the base reference + * IMacroEntry + */ + IPath getBaseReference(); + + /** + * Returns an array of inclusion paths affecting the + * resource when looking for files recursively. + * @return IPath + */ + IPath[] getExclusionPatterns(); + + /** + * Returns a char based representation of the exclusions patterns full path. + */ + public char[][] fullExclusionPatternChars(); + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntry.java index ef0091f9e0c..c3f8f8ad830 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntry.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntry.java @@ -26,39 +26,54 @@ public interface IPathEntry { * Entry kind constant describing a path entry identifying a * required project. */ - int CDT_PROJECT = 2; + int CDT_PROJECT = 1 << 2; /** * Entry kind constant describing a path entry identifying a * folder containing source code to be compiled. */ - int CDT_SOURCE = 3; + int CDT_SOURCE = 1 << 3; /** * Entry kind constant describing a path entry identifying a * include path. */ - int CDT_INCLUDE = 4; + int CDT_INCLUDE = 1 << 4; /** * Entry kind constant describing a path entry representing * a container id. * */ - int CDT_CONTAINER = 5; + int CDT_CONTAINER = 1 << 5; /** * Entry kind constant describing a path entry representing * a macro definition. * */ - int CDT_MACRO = 6; + int CDT_MACRO = 1 << 6; /** * Entry kind constant describing output location * */ - int CDT_OUTPUT = 7; + int CDT_OUTPUT = 1 << 7; + + /** + * Entry kind constant describing a path entry representing + * a file that will be process file as if "#include "file"" appeared as + * the first line of the source file. + */ + int CDT_INCLUDE_FILE = 1 << 8; + + /** + * Entry kind constant describing a path entry representing + * a file that will be process file as if "#include "file"" appeared as + * the first line of the source file but only the macro definitions are kept. + * + */ + int CDT_MACRO_FILE = 1 << 9; /** * Returns the kind of this path entry. @@ -72,6 +87,8 @@ public interface IPathEntry { *
  • CDT_MACRO - this entry describes a macro definition *
  • CDT_CONTAINER - this entry describes a container id *
  • CDT_OUTPUT - this entry describes output location + *
  • CDT_INCLUDE_FILE - this entry describes a file to be process as an include + *
  • CDT_MACRO_FILE - this entry describes a file containing macro definitions */ int getEntryKind(); diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java index 397e6fc5ef7..dcf4a3353b0 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/core/model/IPathEntryContainerExtension.java @@ -18,24 +18,26 @@ import org.eclipse.core.runtime.IPath; */ public interface IPathEntryContainerExtension extends IPathEntryContainer { - /** - * Returns the set of include entries associated with the resource - * and empty array if none. - * - * @param path Workspace relative path. - * @return IIncludeEntry[] - the entries or empty set if none - * @see IPathEntry - */ - IIncludeEntry[] getIncludeEntries(IPath path); - - /** - * Returns the set of macro entries associated with the resource - * and empty array if none. - * - * @param path Workspace relative path. - * @return IMacroEntry[] - the entries or empty set if none - * @see IPathEntry - */ - IMacroEntry[] getMacroEntries(IPath path); + IPathEntry[] getPathEntries(IPath path, int typesMask); +// /** +// * Returns the set of include entries associated with the resource +// * and empty array if none. +// * +// * @param path Workspace relative path. +// * @return IIncludeEntry[] - the entries or empty set if none +// * @see IPathEntry +// */ +// IIncludeEntry[] getIncludeEntries(IPath path); +// +// /** +// * Returns the set of macro entries associated with the resource +// * and empty array if none. +// * +// * @param path Workspace relative path. +// * @return IMacroEntry[] - the entries or empty set if none +// * @see IPathEntry +// */ +// IMacroEntry[] getMacroEntries(IPath path); +// } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DefaultPathEntryStore.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DefaultPathEntryStore.java index 1f27be1623f..2be21430c73 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DefaultPathEntryStore.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/DefaultPathEntryStore.java @@ -25,8 +25,10 @@ import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.model.ICModelStatus; import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IIncludeFileEntry; import org.eclipse.cdt.core.model.ILibraryEntry; import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IMacroFileEntry; import org.eclipse.cdt.core.model.IPathEntry; import org.eclipse.cdt.core.resources.IPathEntryStore; import org.eclipse.cdt.core.resources.IPathEntryStoreListener; @@ -59,10 +61,12 @@ public class DefaultPathEntryStore implements IPathEntryStore, ICDescriptorListe static String ATTRIBUTE_PREFIXMAPPING = "prefixmapping"; //$NON-NLS-1$ static String ATTRIBUTE_EXCLUDING = "excluding"; //$NON-NLS-1$ static String ATTRIBUTE_INCLUDE = "include"; //$NON-NLS-1$ + static String ATTRIBUTE_INCLUDE_FILE= "include-file"; //$NON-NLS-1$ static String ATTRIBUTE_LIBRARY = "library"; //$NON-NLS-1$ static String ATTRIBUTE_SYSTEM = "system"; //$NON-NLS-1$ static String ATTRIBUTE_NAME = "name"; //$NON-NLS-1$ static String ATTRIBUTE_VALUE = "value"; //$NON-NLS-1$ + static String ATTRIBUTE_MACRO_FILE = "macro-file"; //$NON-NLS-1$ static String VALUE_TRUE = "true"; //$NON-NLS-1$ static final IPathEntry[] NO_PATHENTRIES = new IPathEntry[0]; @@ -213,6 +217,11 @@ public class DefaultPathEntryStore implements IPathEntryStore, ICDescriptorListe } return CoreModel.newIncludeEntry(path, basePath, includePath, isSystemInclude, exclusionPatterns, isExported); } + case IPathEntry.CDT_INCLUDE_FILE: { + // include path info + IPath includeFilePath = new Path(element.getAttribute(ATTRIBUTE_INCLUDE_FILE)); + return CoreModel.newIncludeFileEntry(path, basePath, baseRef, includeFilePath, exclusionPatterns, isExported); + } case IPathEntry.CDT_MACRO : { String macroName = element.getAttribute(ATTRIBUTE_NAME); String macroValue = element.getAttribute(ATTRIBUTE_VALUE); @@ -221,6 +230,10 @@ public class DefaultPathEntryStore implements IPathEntryStore, ICDescriptorListe } return CoreModel.newMacroEntry(path, macroName, macroValue, exclusionPatterns, isExported); } + case IPathEntry.CDT_MACRO_FILE : { + IPath macroFilePath = new Path(element.getAttribute(ATTRIBUTE_MACRO_FILE)); + return CoreModel.newMacroFileEntry(path, basePath, baseRef, macroFilePath, exclusionPatterns, isExported); + } case IPathEntry.CDT_CONTAINER : { IPath id = new Path(element.getAttribute(ATTRIBUTE_PATH)); return CoreModel.newContainerEntry(id, isExported); @@ -303,12 +316,23 @@ public class DefaultPathEntryStore implements IPathEntryStore, ICDescriptorListe } break; } + case IPathEntry.CDT_INCLUDE_FILE: { + IIncludeFileEntry include = (IIncludeFileEntry) entries[i]; + IPath includeFilePath = include.getIncludeFilePath(); + element.setAttribute(ATTRIBUTE_INCLUDE_FILE, includeFilePath.toString()); + break; + } case IPathEntry.CDT_MACRO: { IMacroEntry macro = (IMacroEntry) entries[i]; element.setAttribute(ATTRIBUTE_NAME, macro.getMacroName()); element.setAttribute(ATTRIBUTE_VALUE, macro.getMacroValue()); break; } + case IPathEntry.CDT_MACRO_FILE: { + IMacroFileEntry macro = (IMacroFileEntry) entries[i]; + element.setAttribute(ATTRIBUTE_MACRO_FILE, macro.getMacroFilePath().toString()); + break; + } } if (entries[i] instanceof APathEntry) { diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeFileEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeFileEntry.java new file mode 100644 index 00000000000..df8bd3448b7 --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/IncludeFileEntry.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import org.eclipse.cdt.core.model.IIncludeFileEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class IncludeFileEntry extends APathEntry implements IIncludeFileEntry { + + IPath includeFilePath; + + public IncludeFileEntry(IPath resourcePath, IPath basePath, IPath baseRef, IPath includeFilePath, + IPath[] exclusionPatterns, boolean isExported) { + super(IPathEntry.CDT_INCLUDE_FILE, basePath, baseRef, resourcePath, exclusionPatterns, isExported); + this.includeFilePath = (includeFilePath == null) ? Path.EMPTY : includeFilePath; + } + + + /** + * Returns the include path + * + * @return IPath + */ + public IPath getIncludeFilePath() { + return includeFilePath; + } + + public boolean equals(Object obj) { + if (obj instanceof IIncludeFileEntry) { + IIncludeFileEntry otherEntry = (IIncludeFileEntry) obj; + if (!super.equals(otherEntry)) { + return false; + } + if (path == null) { + if (otherEntry.getPath() != null) { + return false; + } + } else { + if (!path.toString().equals(otherEntry.getPath().toString())) { + return false; + } + } + if (includeFilePath == null) { + if (otherEntry.getIncludeFilePath() != null) { + return false; + } + } else { + if (!includeFilePath.toString().equals(otherEntry.getIncludeFilePath().toString())) { + return false; + } + } + return true; + } + return super.equals(obj); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.model.IIncludeEntry#getFullIncludePath() + */ + public IPath getFullIncludeFilePath() { + IPath p; + IPath inc = getIncludeFilePath(); + if (!basePath.isEmpty()) { + IPath loc = basePath; + if (!loc.isAbsolute()) { + IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(loc); + if (res != null) { + loc = res.getLocation(); + } + } + p = loc.append(inc); + return p; + } + + p = inc; + + if (!p.isAbsolute()) { + IPath resPath = getPath(); + IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(resPath); + if (res != null) { + if (res.getType() == IResource.FILE) { + res = res.getParent(); + } + IPath location = res.getLocation(); + if (location != null) { + p = location.append(p); + } + } + } + return p; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(super.toString()); + if (includeFilePath != null && !includeFilePath.isEmpty()) { + sb.append(" includeFilePath:").append(includeFilePath); //$NON-NLS-1$ + } + return sb.toString(); + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MacroFileEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MacroFileEntry.java new file mode 100644 index 00000000000..c20750fc50f --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/MacroFileEntry.java @@ -0,0 +1,117 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import org.eclipse.cdt.core.model.IMacroFileEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class MacroFileEntry extends APathEntry implements IMacroFileEntry { + + IPath macroFilePath; + + public MacroFileEntry(IPath resourcePath, IPath basePath, IPath baseRef, IPath macroFilePath, + IPath[] exclusionPatterns, boolean isExported) { + super(IPathEntry.CDT_MACRO_FILE, basePath, baseRef, resourcePath, exclusionPatterns, isExported); + this.macroFilePath = (macroFilePath == null) ? Path.EMPTY : macroFilePath; + } + + /** + * Returns the macro file path + * + * @return IPath + */ + public IPath getMacroFilePath() { + return macroFilePath; + } + + public boolean equals(Object obj) { + if (obj instanceof IMacroFileEntry) { + IMacroFileEntry otherEntry = (IMacroFileEntry) obj; + if (!super.equals(otherEntry)) { + return false; + } + if (path == null) { + if (otherEntry.getPath() != null) { + return false; + } + } else { + if (!path.toString().equals(otherEntry.getPath().toString())) { + return false; + } + } + if (macroFilePath == null) { + if (otherEntry.getMacroFilePath() != null) { + return false; + } + } else { + if (!macroFilePath.toString().equals(otherEntry.getMacroFilePath().toString())) { + return false; + } + } + return true; + } + return super.equals(obj); + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.model.IIncludeEntry#getFullIncludePath() + */ + public IPath getFullMacroFilePath() { + IPath p; + IPath inc = getMacroFilePath(); + if (!basePath.isEmpty()) { + IPath loc = basePath; + if (!loc.isAbsolute()) { + IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(loc); + if (res != null) { + loc = res.getLocation(); + } + } + p = loc.append(inc); + return p; + } + + p = inc; + + if (!p.isAbsolute()) { + IPath resPath = getPath(); + IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(resPath); + if (res != null) { + if (res.getType() == IResource.FILE) { + res = res.getParent(); + } + IPath location = res.getLocation(); + if (location != null) { + p = location.append(p); + } + } + } + return p; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + public String toString() { + StringBuffer sb = new StringBuffer(); + sb.append(super.toString()); + if (macroFilePath != null && !macroFilePath.isEmpty()) { + sb.append(" macroFilePath:").append(macroFilePath); //$NON-NLS-1$ + } + return sb.toString(); + } + +} diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntry.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntry.java index 0e54b823cb9..454f59a5889 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntry.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntry.java @@ -83,8 +83,12 @@ public class PathEntry implements IPathEntry { return IPathEntry.CDT_LIBRARY; if (kindStr.equalsIgnoreCase("inc")) //$NON-NLS-1$ return IPathEntry.CDT_INCLUDE; + if (kindStr.equalsIgnoreCase("incfile")) //$NON-NLS-1$ + return IPathEntry.CDT_INCLUDE_FILE; if (kindStr.equalsIgnoreCase("mac")) //$NON-NLS-1$ return IPathEntry.CDT_MACRO; + if (kindStr.equalsIgnoreCase("macfile")) //$NON-NLS-1$ + return IPathEntry.CDT_MACRO_FILE; if (kindStr.equalsIgnoreCase("con")) //$NON-NLS-1$ return IPathEntry.CDT_CONTAINER; if (kindStr.equalsIgnoreCase("out")) //$NON-NLS-1$ @@ -106,8 +110,12 @@ public class PathEntry implements IPathEntry { return "lib"; //$NON-NLS-1$ case IPathEntry.CDT_INCLUDE : return "inc"; //$NON-NLS-1$ + case IPathEntry.CDT_INCLUDE_FILE: + return "incfile"; //$NON-NLS-1$ case IPathEntry.CDT_MACRO : return "mac"; //$NON-NLS-1$ + case IPathEntry.CDT_MACRO_FILE: + return "macfile"; //$NON-NLS-1$ case IPathEntry.CDT_CONTAINER : return "con"; //$NON-NLS-1$ case IPathEntry.CDT_OUTPUT : @@ -143,8 +151,12 @@ public class PathEntry implements IPathEntry { return ("Output path"); //$NON-NLS-1$ case IPathEntry.CDT_INCLUDE : return ("Include path"); //$NON-NLS-1$ + case IPathEntry.CDT_INCLUDE_FILE : + return ("Include-file path"); //$NON-NLS-1$ case IPathEntry.CDT_MACRO : return ("Symbol definition"); //$NON-NLS-1$ + case IPathEntry.CDT_MACRO_FILE : + return ("Symbol-file definition"); //$NON-NLS-1$ case IPathEntry.CDT_CONTAINER : return ("Contributed paths"); //$NON-NLS-1$ } diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java index 90da1338cd8..243f91f2139 100644 --- a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryManager.java @@ -10,7 +10,6 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.model; -import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; @@ -24,7 +23,6 @@ import org.eclipse.cdt.core.ICDescriptor; import org.eclipse.cdt.core.ICExtensionReference; import org.eclipse.cdt.core.model.CModelException; import org.eclipse.cdt.core.model.CoreModel; -import org.eclipse.cdt.core.model.CoreModelUtil; import org.eclipse.cdt.core.model.ElementChangedEvent; import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; @@ -35,8 +33,10 @@ import org.eclipse.cdt.core.model.ICProject; import org.eclipse.cdt.core.model.IContainerEntry; import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IIncludeFileEntry; import org.eclipse.cdt.core.model.ILibraryEntry; import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IMacroFileEntry; import org.eclipse.cdt.core.model.IOpenable; import org.eclipse.cdt.core.model.IOutputEntry; import org.eclipse.cdt.core.model.IPathEntry; @@ -50,15 +50,11 @@ import org.eclipse.cdt.core.model.PathEntryContainerChanged; import org.eclipse.cdt.core.model.PathEntryContainerInitializer; import org.eclipse.cdt.core.resources.IPathEntryStore; import org.eclipse.cdt.core.resources.IPathEntryStoreListener; -import org.eclipse.cdt.core.resources.IPathEntryVariableManager; import org.eclipse.cdt.core.resources.PathEntryStoreChangedEvent; import org.eclipse.core.resources.IMarker; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IWorkspace; -import org.eclipse.core.resources.IWorkspaceRoot; import org.eclipse.core.resources.IWorkspaceRunnable; -import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IConfigurationElement; import org.eclipse.core.runtime.IExtension; @@ -98,14 +94,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange static final IPathEntry[] NO_PATHENTRIES = new IPathEntry[0]; - static final IIncludeEntry[] NO_INCLUDENTRIES = new IIncludeEntry[0]; + static final IIncludeEntry[] NO_INCLUDE_ENTRIES = new IIncludeEntry[0]; - static final IMacroEntry[] NO_MACROENTRIES = new IMacroEntry[0]; + static final IIncludeFileEntry[] NO_INCLUDE_FILE_ENTRIES = new IIncludeFileEntry[0]; + + static final IMacroEntry[] NO_MACRO_ENTRIES = new IMacroEntry[0]; + + static final IMacroFileEntry[] NO_MACRO_FILE_ENTRIES = new IMacroFileEntry[0]; static final IPathEntryContainer[] NO_PATHENTRYCONTAINERS = new IPathEntryContainer[0]; - static final IMarker[] NO_MARKERS = new IMarker[0]; - // Synchronized the access of the cache entries. protected Map resolvedMap = new Hashtable(); @@ -167,12 +165,89 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange return pathEntryManager; } + public IIncludeFileEntry[] getIncludeFileEntries(IPath resPath) throws CModelException { + ICElement celement = CoreModel.getDefault().create(resPath); + if (celement instanceof ITranslationUnit) { + return getIncludeFileEntries((ITranslationUnit)celement); + } + return NO_INCLUDE_FILE_ENTRIES; + } + + public IIncludeFileEntry[] getIncludeFileEntries(ITranslationUnit cunit) throws CModelException { + ArrayList includeFileList = new ArrayList(); + ICProject cproject = cunit.getCProject(); + IPath resPath = cunit.getPath(); + // Do this first so the containers get inialized. + ArrayList resolvedListEntries = getResolvedPathEntries(cproject, false); + for (int i = 0; i < resolvedListEntries.size(); ++i) { + IPathEntry entry = (IPathEntry)resolvedListEntries.get(i); + if (entry.getEntryKind() == IPathEntry.CDT_INCLUDE_FILE) { + includeFileList.add(entry); + } + } + IPathEntryContainer[] containers = getPathEntryContainers(cproject); + for (int i = 0; i < containers.length; ++i) { + if (containers[i] instanceof IPathEntryContainerExtension) { + IPathEntryContainerExtension extension = (IPathEntryContainerExtension)containers[i]; + IIncludeFileEntry[] incs = (IIncludeFileEntry[])extension.getPathEntries(resPath, IPathEntry.CDT_INCLUDE_FILE); + includeFileList.addAll(Arrays.asList(incs)); + } + } + + IIncludeFileEntry[] includeFiles = (IIncludeFileEntry[]) includeFileList.toArray(new IIncludeFileEntry[includeFileList.size()]); + // Clear the list since we are reusing it. + includeFileList.clear(); + + // We need to reorder the include/macros: + // includes with the closest match to the resource will come first + // /project/src/file.c --> /usr/local/include + // /project --> /usr/include + // + // /usr/local/include must come first. + // + int count = resPath.segmentCount(); + for (int i = 0; i < count; i++) { + IPath newPath = resPath.removeLastSegments(i); + for (int j = 0; j < includeFiles.length; j++) { + IPath otherPath = includeFiles[j].getPath(); + if (newPath.equals(otherPath)) { + includeFileList.add(includeFiles[j]); + } + } + } + + // Since the include that comes from a project contribution are not + // tied to a resource they are added last. + for (int i = 0; i < resolvedListEntries.size(); i++) { + IPathEntry entry = (IPathEntry)resolvedListEntries.get(i); + if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) { + IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath()); + if (res != null && res.getType() == IResource.PROJECT) { + ICProject refCProject = CoreModel.getDefault().create((IProject)res); + if (refCProject != null) { + IPathEntry[] projEntries = refCProject.getResolvedPathEntries(); + for (int j = 0; j < projEntries.length; j++) { + IPathEntry projEntry = projEntries[j]; + if (projEntry.isExported()) { + if (projEntry.getEntryKind() == IPathEntry.CDT_INCLUDE_FILE) { + IIncludeFileEntry includeFile = (IIncludeFileEntry)projEntry; + includeFileList.add(includeFile); + } + } + } + } + } + } + } + return (IIncludeFileEntry[])includeFileList.toArray(new IIncludeFileEntry[includeFileList.size()]); + } + public IIncludeEntry[] getIncludeEntries(IPath resPath) throws CModelException { ICElement celement = CoreModel.getDefault().create(resPath); if (celement instanceof ITranslationUnit) { return getIncludeEntries((ITranslationUnit)celement); } - return NO_INCLUDENTRIES; + return NO_INCLUDE_ENTRIES; } public IIncludeEntry[] getIncludeEntries(ITranslationUnit cunit) throws CModelException { @@ -190,7 +265,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange IPathEntryContainer[] containers = getPathEntryContainers(cproject); for (int i = 0; i < containers.length; ++i) { if (containers[i] instanceof IPathEntryContainerExtension) { - IIncludeEntry[] incs = ((IPathEntryContainerExtension)containers[i]).getIncludeEntries(resPath); + IPathEntryContainerExtension extension = (IPathEntryContainerExtension)containers[i]; + IIncludeEntry[] incs = (IIncludeEntry[]) extension.getPathEntries(resPath, IPathEntry.CDT_INCLUDE_FILE); includeList.addAll(Arrays.asList(incs)); } } @@ -248,7 +324,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange if (celement instanceof ITranslationUnit) { return getMacroEntries((ITranslationUnit)celement); } - return NO_MACROENTRIES; + return NO_MACRO_ENTRIES; } public IMacroEntry[] getMacroEntries(ITranslationUnit cunit) throws CModelException { @@ -266,7 +342,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange IPathEntryContainer[] containers = getPathEntryContainers(cproject); for (int i = 0; i < containers.length; ++i) { if (containers[i] instanceof IPathEntryContainerExtension) { - IMacroEntry[] incs = ((IPathEntryContainerExtension)containers[i]).getMacroEntries(resPath); + IPathEntryContainerExtension extension = (IPathEntryContainerExtension)containers[i]; + IMacroEntry[] incs = (IMacroEntry[])extension.getPathEntries(resPath, IPathEntry.CDT_MACRO); macroList.addAll(Arrays.asList(incs)); } } @@ -320,10 +397,86 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange } } - return (IMacroEntry[])symbolMap.values().toArray(NO_MACROENTRIES); + return (IMacroEntry[])symbolMap.values().toArray(NO_MACRO_ENTRIES); } + public IMacroFileEntry[] getMacroFileEntries(IPath resPath) throws CModelException { + ICElement celement = CoreModel.getDefault().create(resPath); + if (celement instanceof ITranslationUnit) { + return getMacroFileEntries((ITranslationUnit)celement); + } + return NO_MACRO_FILE_ENTRIES; + } + + public IMacroFileEntry[] getMacroFileEntries(ITranslationUnit cunit) throws CModelException { + ArrayList macroFileList = new ArrayList(); + ICProject cproject = cunit.getCProject(); + IPath resPath = cunit.getPath(); + // Do this first so the containers get inialized. + ArrayList resolvedListEntries = getResolvedPathEntries(cproject, false); + for (int i = 0; i < resolvedListEntries.size(); ++i) { + IPathEntry entry = (IPathEntry)resolvedListEntries.get(i); + if (entry.getEntryKind() == IPathEntry.CDT_MACRO_FILE) { + macroFileList.add(entry); + } + } + IPathEntryContainer[] containers = getPathEntryContainers(cproject); + for (int i = 0; i < containers.length; ++i) { + if (containers[i] instanceof IPathEntryContainerExtension) { + IPathEntryContainerExtension extension = (IPathEntryContainerExtension)containers[i]; + IMacroFileEntry[] macFiles = (IMacroFileEntry[])extension.getPathEntries(resPath, IPathEntry.CDT_MACRO_FILE); + macroFileList.addAll(Arrays.asList(macFiles)); + } + } + + IMacroFileEntry[] macroFiles = (IMacroFileEntry[]) macroFileList.toArray(new IMacroFileEntry[macroFileList.size()]); + macroFileList.clear(); + + // We need to reorder the macro files: + // with the closest match to the resource coming first + // /project/src/file.c --> /usr/local/include/macrofile + // /project --> /usr/include/macrofile + // + // /usr/local/include/macrofile must come first. + // + int count = resPath.segmentCount(); + for (int i = 0; i < count; i++) { + IPath newPath = resPath.removeLastSegments(i); + for (int j = 0; j < macroFiles.length; j++) { + IPath otherPath = macroFiles[j].getPath(); + if (newPath.equals(otherPath)) { + macroFileList.add(macroFiles[j]); + } + } + } + + // Since the macroFile that comes from a project contribution are not + // tied to a resource they are added last. + for (int i = 0; i < resolvedListEntries.size(); i++) { + IPathEntry entry = (IPathEntry)resolvedListEntries.get(i); + if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) { + IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath()); + if (res != null && res.getType() == IResource.PROJECT) { + ICProject refCProject = CoreModel.getDefault().create((IProject)res); + if (refCProject != null) { + IPathEntry[] projEntries = refCProject.getResolvedPathEntries(); + for (int j = 0; j < projEntries.length; j++) { + IPathEntry projEntry = projEntries[j]; + if (projEntry.isExported()) { + if (projEntry.getEntryKind() == IPathEntry.CDT_MACRO_FILE) { + IMacroFileEntry macroFile = (IMacroFileEntry)projEntry; + macroFileList.add(macroFile); + } + } + } + } + } + } + } + return (IMacroFileEntry[])macroFileList.toArray(NO_MACRO_FILE_ENTRIES); + } + /** * Return the cached entries, if no cache null. * @param cproject @@ -377,7 +530,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange IPathEntry[] containerEntries = container.getPathEntries(); if (containerEntries != null) { for (int j = 0; j < containerEntries.length; j++) { - IPathEntry newEntry = cloneEntryAndExpand(projectPath, containerEntries[j]); + IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath, containerEntries[j]); listEntries.add(newEntry); } } @@ -424,17 +577,17 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange IPathEntry[] containerEntries = container.getPathEntries(); if (containerEntries != null) { for (int j = 0; j < containerEntries.length; j++) { - IPathEntry newEntry = cloneEntryAndExpand(projectPath, containerEntries[j]); + IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath, containerEntries[j]); resolvedEntries.add(newEntry); } } } else { - resolvedEntries.add(cloneEntryAndExpand(projectPath, entry)); + resolvedEntries.add(PathEntryUtil.cloneEntryAndExpand(projectPath, entry)); } } } else { - IPathEntry clone = cloneEntryAndExpand(projectPath, entry); - IPathEntry e = getExpandedPathEntry(clone, cproject); + IPathEntry clone = PathEntryUtil.cloneEntryAndExpand(projectPath, entry); + IPathEntry e = PathEntryUtil.getExpandedPathEntry(clone, cproject); if (e != null) { resolvedEntries.add(e); } @@ -450,7 +603,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange problemList.add(status); } for (int j = 0; j < finalEntries.length; j++) { - status = validatePathEntry(cproject, finalEntries[j], true, false); + status = PathEntryUtil.validatePathEntry(cproject, finalEntries[j], true, false); if (!status.isOK()) { problemList.add(status); } @@ -458,19 +611,19 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange ICModelStatus[] problems = new ICModelStatus[problemList.size()]; problemList.toArray(problems); IProject project = cproject.getProject(); - if (hasPathEntryProblemMarkersChange(project, problems)) { + if (PathEntryUtil.hasPathEntryProblemMarkersChange(project, problems)) { generateMarkers(project, problems); } } // Check for duplication in the sources - List dups = checkForDuplication(resolvedEntries, IPathEntry.CDT_SOURCE); + List dups = PathEntryUtil.checkForDuplication(resolvedEntries, IPathEntry.CDT_SOURCE); if (dups.size() > 0) { resolvedEntries.removeAll(dups); } // Check for duplication in the outputs - dups = checkForDuplication(resolvedEntries, IPathEntry.CDT_OUTPUT); + dups = PathEntryUtil.checkForDuplication(resolvedEntries, IPathEntry.CDT_OUTPUT); if (dups.size() > 0) { resolvedEntries.removeAll(dups); } @@ -480,190 +633,6 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange return resolvedEntries; } - private IPathEntry getExpandedPathEntry(IPathEntry entry, ICProject cproject) throws CModelException { - switch (entry.getEntryKind()) { - case IPathEntry.CDT_INCLUDE : { - IIncludeEntry includeEntry = (IIncludeEntry)entry; - IPath refPath = includeEntry.getBaseReference(); - if (refPath != null && !refPath.isEmpty()) { - IPath includePath = includeEntry.getIncludePath(); - if (refPath.isAbsolute()) { - IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(refPath); - if (res != null && res.getType() == IResource.PROJECT) { - IProject project = (IProject)res; - if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) { - ICProject refCProject = CoreModel.getDefault().create(project); - if (refCProject != null) { - IPathEntry[] entries = getResolvedPathEntries(refCProject); - for (int i = 0; i < entries.length; i++) { - if (entries[i].getEntryKind() == IPathEntry.CDT_INCLUDE) { - IIncludeEntry refEntry = (IIncludeEntry)entries[i]; - if (refEntry.getIncludePath().equals(includePath)) { - IPath newBasePath = refEntry.getBasePath(); - // If the includePath is - // relative give a new basepath - // if none - if (!newBasePath.isAbsolute() && !includePath.isAbsolute()) { - IResource refRes; - if (!newBasePath.isEmpty()) { - refRes = cproject.getCModel().getWorkspace().getRoot().findMember( - newBasePath); - } else { - IPath refResPath = refEntry.getPath(); - refRes = cproject.getCModel().getWorkspace().getRoot().findMember( - refResPath); - } - if (refRes != null) { - if (refRes.getType() == IResource.FILE) { - refRes = refRes.getParent(); - } - newBasePath = refRes.getLocation().append(newBasePath); - } - } - return CoreModel.newIncludeEntry(includeEntry.getPath(), newBasePath, includePath); - } - } - } - } - } - } - } else { // Container ref - IPathEntryContainer container = getPathEntryContainer(refPath, cproject); - if (container != null) { - IPathEntry[] entries = container.getPathEntries(); - for (int i = 0; i < entries.length; i++) { - if (entries[i].getEntryKind() == IPathEntry.CDT_INCLUDE) { - IIncludeEntry refEntry = (IIncludeEntry)entries[i]; - if (refEntry.getIncludePath().equals(includePath)) { - IPath newBasePath = refEntry.getBasePath(); - return CoreModel.newIncludeEntry(includeEntry.getPath(), newBasePath, includePath); - } - } - } - } - } - } - break; - } - - case IPathEntry.CDT_MACRO : { - IMacroEntry macroEntry = (IMacroEntry)entry; - IPath refPath = macroEntry.getBaseReference(); - if (refPath != null && !refPath.isEmpty()) { - String name = macroEntry.getMacroName(); - if (refPath.isAbsolute()) { - IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(refPath); - if (res != null && res.getType() == IResource.PROJECT) { - IProject project = (IProject)res; - if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) { - ICProject refCProject = CoreModel.getDefault().create(project); - if (refCProject != null) { - IPathEntry[] entries = getResolvedPathEntries(refCProject); - for (int i = 0; i < entries.length; i++) { - if (entries[i].getEntryKind() == IPathEntry.CDT_MACRO) { - IMacroEntry refEntry = (IMacroEntry)entries[i]; - if (refEntry.getMacroName().equals(name)) { - String value = refEntry.getMacroValue(); - return CoreModel.newMacroEntry(macroEntry.getPath(), name, value); - } - } - } - } - } - } - } else { // Container ref - IPathEntryContainer container = getPathEntryContainer(refPath, cproject); - if (container != null) { - IPathEntry[] entries = container.getPathEntries(); - for (int i = 0; i < entries.length; i++) { - if (entries[i].getEntryKind() == IPathEntry.CDT_MACRO) { - IMacroEntry refEntry = (IMacroEntry)entries[i]; - if (refEntry.getMacroName().equals(name)) { - String value = refEntry.getMacroValue(); - return CoreModel.newMacroEntry(macroEntry.getPath(), name, value); - } - } - } - } - } - } - break; - } - - case IPathEntry.CDT_LIBRARY : { - ILibraryEntry libEntry = (ILibraryEntry)entry; - IPath refPath = libEntry.getBaseReference(); - if (refPath != null && !refPath.isEmpty()) { - IPath libraryPath = libEntry.getLibraryPath(); - if (refPath.isAbsolute()) { - IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(refPath); - if (res != null && res.getType() == IResource.PROJECT) { - IProject project = (IProject)res; - if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) { - ICProject refCProject = CoreModel.getDefault().create(project); - if (refCProject != null) { - IPathEntry[] entries = getResolvedPathEntries(refCProject); - for (int i = 0; i < entries.length; i++) { - if (entries[i].getEntryKind() == IPathEntry.CDT_LIBRARY) { - ILibraryEntry refEntry = (ILibraryEntry)entries[i]; - if (refEntry.getLibraryPath().equals(libraryPath)) { - IPath newBasePath = refEntry.getBasePath(); - // If the libraryPath is - // relative give a new basepath - // if none - if (!newBasePath.isAbsolute() && !libraryPath.isAbsolute()) { - IResource refRes; - if (!newBasePath.isEmpty()) { - refRes = cproject.getCModel().getWorkspace().getRoot().findMember( - newBasePath); - } else { - IPath refResPath = refEntry.getPath(); - refRes = cproject.getCModel().getWorkspace().getRoot().findMember( - refResPath); - } - if (refRes != null) { - if (refRes.getType() == IResource.FILE) { - refRes = refRes.getParent(); - } - newBasePath = refRes.getLocation().append(newBasePath); - } - } - - return CoreModel.newLibraryEntry(entry.getPath(), newBasePath, - refEntry.getLibraryPath(), refEntry.getSourceAttachmentPath(), - refEntry.getSourceAttachmentRootPath(), - refEntry.getSourceAttachmentPrefixMapping(), false); - } - } - } - } - } - } - } else { // Container ref - IPathEntryContainer container = getPathEntryContainer(refPath, cproject); - if (container != null) { - IPathEntry[] entries = container.getPathEntries(); - for (int i = 0; i < entries.length; i++) { - if (entries[i].getEntryKind() == IPathEntry.CDT_LIBRARY) { - ILibraryEntry refEntry = (ILibraryEntry)entries[i]; - if (refEntry.getPath().equals(libraryPath)) { - return CoreModel.newLibraryEntry(entry.getPath(), refEntry.getBasePath(), - refEntry.getLibraryPath(), refEntry.getSourceAttachmentPath(), - refEntry.getSourceAttachmentRootPath(), - refEntry.getSourceAttachmentPrefixMapping(), false); - } - } - } - } - } - } - break; - } - - } - return entry; - } - public void setRawPathEntries(ICProject cproject, IPathEntry[] newEntries, IProgressMonitor monitor) throws CModelException { try { IPathEntry[] oldResolvedEntries = getCachedResolvedPathEntries(cproject); @@ -1095,6 +1064,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange } break; } + case IPathEntry.CDT_INCLUDE_FILE : { + IIncludeFileEntry includeFile = (IIncludeFileEntry)entries[i]; + entry = CoreModel.newIncludeFileEntry(resourcePath, includeFile.getBasePath(), + includeFile.getBaseReference(), includeFile.getIncludeFilePath(), + includeFile.getExclusionPatterns(), includeFile.isExported()); + break; + } case IPathEntry.CDT_LIBRARY : { ILibraryEntry library = (ILibraryEntry)entries[i]; IPath sourcePath = library.getSourceAttachmentPath(); @@ -1128,6 +1104,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange } break; } + case IPathEntry.CDT_MACRO_FILE : { + IMacroFileEntry macro = (IMacroFileEntry)entries[i]; + entry = CoreModel.newMacroFileEntry(resourcePath, macro.getBasePath(), + macro.getBaseReference(), macro.getMacroFilePath(), + macro.getExclusionPatterns(), macro.isExported()); + break; + } case IPathEntry.CDT_OUTPUT : { IOutputEntry out = (IOutputEntry)entries[i]; entry = CoreModel.newOutputEntry(resourcePath, out.getExclusionPatterns()); @@ -1178,9 +1161,9 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange * @see org.eclipse.core.resources.IWorkspaceRunnable#run(org.eclipse.core.runtime.IProgressMonitor) */ public void run(IProgressMonitor mon) throws CoreException { - flushPathEntryProblemMarkers(project); + PathEntryUtil.flushPathEntryProblemMarkers(project); for (int i = 0; i < problems.length; ++i) { - createPathEntryProblemMarker(project, problems[i]); + PathEntryUtil.createPathEntryProblemMarker(project, problems[i]); } } }, null); @@ -1304,13 +1287,27 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange flag = ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE; break; } - case IPathEntry.CDT_MACRO : { + case IPathEntry.CDT_INCLUDE_FILE: { + IIncludeFileEntry includeFile = (IIncludeFileEntry)entry; + IPath path = includeFile.getPath(); + celement = CoreModel.getDefault().create(path); + flag = ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE; + break; + } + case IPathEntry.CDT_MACRO : { IMacroEntry macro = (IMacroEntry)entry; IPath path = macro.getPath(); celement = CoreModel.getDefault().create(path); flag = ICElementDelta.F_CHANGED_PATHENTRY_MACRO; break; } + case IPathEntry.CDT_MACRO_FILE: { + IMacroFileEntry macro = (IMacroFileEntry)entry; + IPath path = macro.getPath(); + celement = CoreModel.getDefault().create(path); + flag = ICElementDelta.F_CHANGED_PATHENTRY_MACRO; + break; + } case IPathEntry.CDT_CONTAINER : { //IContainerEntry container = (IContainerEntry) entry; //celement = cproject; @@ -1464,14 +1461,14 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange if (markers != null && markers.length > 0) { ArrayList problemList = new ArrayList(); for (int j = 0; j < entries.length; j++) { - ICModelStatus status = validatePathEntry(cProjects[i], entries[j], true, false); + ICModelStatus status = PathEntryUtil.validatePathEntry(cProjects[i], entries[j], true, false); if (!status.isOK()) { problemList.add(status); } } ICModelStatus[] problems = new ICModelStatus[problemList.size()]; problemList.toArray(problems); - if (hasPathEntryProblemMarkersChange(project, problems)) { + if (PathEntryUtil.hasPathEntryProblemMarkersChange(project, problems)) { generateMarkers(project, problems); } } @@ -1532,392 +1529,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange return false; } - protected IPathEntry cloneEntryAndExpand(IPath rpath, IPathEntry entry) { - - // get the path - IPath entryPath = entry.getPath(); - if (entryPath == null) { - entryPath = Path.EMPTY; - } - IPath resourcePath = (entryPath.isAbsolute()) ? entryPath : rpath.append(entryPath); - - IPathEntryVariableManager varManager = CCorePlugin.getDefault().getPathEntryVariableManager(); - switch (entry.getEntryKind()) { - case IPathEntry.CDT_INCLUDE : { - IIncludeEntry include = (IIncludeEntry)entry; - - IPath basePath = include.getBasePath(); - basePath = varManager.resolvePath(basePath); - - IPath includePath = include.getIncludePath(); - includePath = varManager.resolvePath(includePath); - - return CoreModel.newIncludeEntry(resourcePath, basePath, includePath, - include.isSystemInclude(), include.getExclusionPatterns(), include.isExported()); - } - case IPathEntry.CDT_LIBRARY : { - ILibraryEntry library = (ILibraryEntry)entry; - - IPath basePath = library.getBasePath(); - basePath = varManager.resolvePath(basePath); - - IPath libraryPath = library.getLibraryPath(); - libraryPath = varManager.resolvePath(libraryPath); - - IPath sourceAttachmentPath = library.getSourceAttachmentPath(); - sourceAttachmentPath = varManager.resolvePath(sourceAttachmentPath); - - IPath sourceAttachmentRootPath = library.getSourceAttachmentRootPath(); - sourceAttachmentRootPath = varManager.resolvePath(sourceAttachmentRootPath); - - IPath sourceAttachmentPrefixMapping = library.getSourceAttachmentPrefixMapping(); - sourceAttachmentPrefixMapping = varManager.resolvePath(sourceAttachmentPrefixMapping); - - return CoreModel.newLibraryEntry(resourcePath, basePath, libraryPath, - sourceAttachmentPath, sourceAttachmentRootPath, - sourceAttachmentPrefixMapping, library.isExported()); - } - case IPathEntry.CDT_MACRO : { - IMacroEntry macro = (IMacroEntry)entry; - return CoreModel.newMacroEntry(resourcePath, macro.getMacroName(), macro.getMacroValue(), - macro.getExclusionPatterns(), macro.isExported()); - } - case IPathEntry.CDT_OUTPUT : { - IOutputEntry out = (IOutputEntry)entry; - return CoreModel.newOutputEntry(resourcePath, out.getExclusionPatterns()); - } - case IPathEntry.CDT_PROJECT : { - IProjectEntry projEntry = (IProjectEntry)entry; - return CoreModel.newProjectEntry(projEntry.getPath(), projEntry.isExported()); - } - case IPathEntry.CDT_SOURCE : { - ISourceEntry source = (ISourceEntry)entry; - return CoreModel.newSourceEntry(resourcePath, source.getExclusionPatterns()); - } - case IPathEntry.CDT_CONTAINER : { - return CoreModel.newContainerEntry(entry.getPath(), entry.isExported()); - } - } - return entry; - } - public ICModelStatus validatePathEntry(ICProject cProject, IPathEntry[] entries) { - - // Check duplication. - for (int i = 0; i < entries.length; i++) { - IPathEntry entry = entries[i]; - if (entry == null) { - continue; - } - for (int j = 0; j < entries.length; j++) { - IPathEntry otherEntry = entries[j]; - if (otherEntry == null) { - continue; - } - if (entry != otherEntry && otherEntry.equals(entry)) { - StringBuffer errMesg = new StringBuffer(CCorePlugin.getResourceString("CoreModel.PathEntry.DuplicateEntry")); //$NON-NLS-1$ - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); - } - } - } - - // check duplication of sources - List dups = checkForDuplication(Arrays.asList(entries), IPathEntry.CDT_SOURCE); - if (dups.size() > 0) { - ICModelStatus[] cmodelStatus = new ICModelStatus[dups.size()]; - for (int i = 0; i < dups.size(); ++i) { - StringBuffer errMesg = new StringBuffer(CCorePlugin.getResourceString("CoreModel.PathEntry.DuplicateEntry")); //$NON-NLS-1$ - cmodelStatus[i] = new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); - } - return CModelStatus.newMultiStatus(ICModelStatusConstants.INVALID_PATHENTRY, cmodelStatus); - } - - // check duplication of Outputs - dups = checkForDuplication(Arrays.asList(entries), IPathEntry.CDT_OUTPUT); - if (dups.size() > 0) { - ICModelStatus[] cmodelStatus = new ICModelStatus[dups.size()]; - for (int i = 0; i < dups.size(); ++i) { - StringBuffer errMesg = new StringBuffer(CCorePlugin.getResourceString("CoreModel.PathEntry.DuplicateEntry")); //$NON-NLS-1$ - cmodelStatus[i] = new CModelStatus(ICModelStatusConstants.NAME_COLLISION, errMesg.toString()); - } - return CModelStatus.newMultiStatus(ICModelStatusConstants.INVALID_PATHENTRY, cmodelStatus); - } - - // allow nesting source entries in each other as long as the outer entry - // excludes the inner one - for (int i = 0; i < entries.length; i++) { - IPathEntry entry = entries[i]; - if (entry == null) { - continue; - } - IPath entryPath = entry.getPath(); - int kind = entry.getEntryKind(); - if (kind == IPathEntry.CDT_SOURCE) { - for (int j = 0; j < entries.length; j++) { - IPathEntry otherEntry = entries[j]; - if (otherEntry == null) { - continue; - } - int otherKind = otherEntry.getEntryKind(); - IPath otherPath = otherEntry.getPath(); - if (entry != otherEntry && (otherKind == IPathEntry.CDT_SOURCE)) { - char[][] exclusionPatterns = ((ISourceEntry)otherEntry).fullExclusionPatternChars(); - if (otherPath.isPrefixOf(entryPath) && !otherPath.equals(entryPath) - && !CoreModelUtil.isExcluded(entryPath.append("*"), exclusionPatterns)) { //$NON-NLS-1$ - - String exclusionPattern = entryPath.removeFirstSegments(otherPath.segmentCount()).segment(0); - if (CoreModelUtil.isExcluded(entryPath, exclusionPatterns)) { - StringBuffer errMesg = new StringBuffer( - CCorePlugin.getResourceString("CoreModel.PathEntry.NestedEntry")); //$NON-NLS-1$ - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); - } else if (otherKind == IPathEntry.CDT_SOURCE) { - exclusionPattern += '/'; - StringBuffer errMesg = new StringBuffer( - CCorePlugin.getResourceString("CoreModel.PathEntry.NestedEntry")); //$NON-NLS-1$ - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); - } else { - StringBuffer errMesg = new StringBuffer( - CCorePlugin.getResourceString("CoreModel.PathEntry.NestedEntry")); //$NON-NLS-1$ - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); //$NON-NLS-1$ - } - } - } - } - } - } - - return CModelStatus.VERIFIED_OK; + return PathEntryUtil.validatePathEntry(cProject, entries); } public ICModelStatus validatePathEntry(ICProject cProject, IPathEntry entry, boolean checkSourceAttachment, boolean recurseInContainers) { - IProject project = cProject.getProject(); - IPath path = entry.getPath(); - if (entry.getEntryKind() != IPathEntry.CDT_PROJECT) { - if (!isValidWorkspacePath(project, path)) { - return new CModelStatus( - ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.0") + path.toOSString() + " for " + ((PathEntry)entry).getKindString()); //$NON-NLS-1$ //$NON-NLS-2$ - } - } - - switch (entry.getEntryKind()) { - case IPathEntry.CDT_INCLUDE : { - IIncludeEntry include = (IIncludeEntry)entry; - IPath includePath = include.getFullIncludePath(); - if (!isValidExternalPath(includePath)) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.2") + " (" + includePath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - } - if (!isValidBasePath(include.getBasePath())) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.1") + " (" + includePath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - } - break; - } - case IPathEntry.CDT_LIBRARY : { - ILibraryEntry library = (ILibraryEntry)entry; - if (checkSourceAttachment) { - IPath sourceAttach = library.getSourceAttachmentPath(); - if (sourceAttach != null) { - if (!sourceAttach.isAbsolute()) { - if (!isValidWorkspacePath(project, sourceAttach) || !isValidExternalPath(sourceAttach)) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.3") + " (" + sourceAttach.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ - } - } - } - } - IPath libraryPath = library.getFullLibraryPath(); - if (!isValidExternalPath(libraryPath)) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.4") + " (" + libraryPath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - } - if (!isValidBasePath(library.getBasePath())) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.7") + " (" + libraryPath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ - } - break; - } - case IPathEntry.CDT_PROJECT : { - IProjectEntry projEntry = (IProjectEntry)entry; - path = projEntry.getPath(); - IProject reqProject = project.getWorkspace().getRoot().getProject(path.segment(0)); - if (!reqProject.isAccessible()) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.5")); //$NON-NLS-1$ - } - if (! (CoreModel.hasCNature(reqProject) || CoreModel.hasCCNature(reqProject))) { - return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, - CoreModelMessages.getString("PathEntryManager.6")); //$NON-NLS-1$ - } - break; - } - case IPathEntry.CDT_CONTAINER : - if (recurseInContainers) { - try { - IPathEntryContainer cont = getPathEntryContainer((IContainerEntry)entry, cProject); - IPathEntry[] contEntries = cont.getPathEntries(); - for (int i = 0; i < contEntries.length; i++) { - ICModelStatus status = validatePathEntry(cProject, contEntries[i], checkSourceAttachment, false); - if (!status.isOK()) { - return status; - } - } - } catch (CModelException e) { - return new CModelStatus(e); - } - } - break; - } - return CModelStatus.VERIFIED_OK; + return PathEntryUtil.validatePathEntry(cProject, entry, checkSourceAttachment, recurseInContainers); } - private boolean isValidWorkspacePath(IProject project, IPath path) { - if (path == null) { - return false; - } - IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); - // We accept empy path as the project - IResource res = null; - if (path.isAbsolute()) { - res = workspaceRoot.findMember(path); - } else { - res = project.findMember(path); - } - return (res != null && res.isAccessible()); - } - - private boolean isValidExternalPath(IPath path) { - if (path != null) { - File file = path.toFile(); - if (file != null) { - return file.exists(); - } - } - return false; - } - - private boolean isValidBasePath(IPath path) { - if (!path.isEmpty() && !path.isAbsolute()) { - IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path); - if (res == null || !res.isAccessible()) { - return false; - } - } - return true; - } - - private List checkForDuplication(List pathEntries, int type) { - List duplicate = new ArrayList(pathEntries.size()); - for (int i = 0; i < pathEntries.size(); ++i) { - IPathEntry pathEntry = (IPathEntry)pathEntries.get(i); - if (pathEntry.getEntryKind() == type) { - for (int j = 0; j < pathEntries.size(); ++j) { - IPathEntry otherEntry = (IPathEntry)pathEntries.get(j); - if (otherEntry.getEntryKind() == type) { - if (!pathEntry.equals(otherEntry)) { - if (!duplicate.contains(pathEntry)) { - if (pathEntry.getPath().equals(otherEntry.getPath())) { - // duplication of sources - duplicate.add(otherEntry); - } - } - } - } - } - } - } - return duplicate; - } - - /** - * Record a new marker denoting a pathentry problem - */ - void createPathEntryProblemMarker(IProject project, ICModelStatus status) { - int severity = code2Severity(status); - try { - IMarker marker = project.createMarker(ICModelMarker.PATHENTRY_PROBLEM_MARKER); - marker.setAttributes(new String[]{IMarker.MESSAGE, IMarker.SEVERITY, IMarker.LOCATION, - ICModelMarker.PATHENTRY_FILE_FORMAT,}, new Object[]{status.getMessage(), new Integer(severity), "pathentry",//$NON-NLS-1$ - "false",//$NON-NLS-1$ - }); - } catch (CoreException e) { - // could not create marker: cannot do much - //e.printStackTrace(); - } - } - - /** - * Remove all markers denoting pathentry problems - */ - protected void flushPathEntryProblemMarkers(IProject project) { - IWorkspace workspace = project.getWorkspace(); - - try { - IMarker[] markers = getPathEntryProblemMarkers(project); - workspace.deleteMarkers(markers); - } catch (CoreException e) { - // could not flush markers: not much we can do - //e.printStackTrace(); - } - } - - /** - * get all markers denoting pathentry problems - */ - protected IMarker[] getPathEntryProblemMarkers(IProject project) { - - try { - IMarker[] markers = project.findMarkers(ICModelMarker.PATHENTRY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); - if (markers != null) { - return markers; - } - } catch (CoreException e) { - //e.printStackTrace(); - } - return NO_MARKERS; - } - - protected boolean hasPathEntryProblemMarkersChange(IProject project, ICModelStatus[] status) { - IMarker[] markers = getPathEntryProblemMarkers(project); - if (markers.length != status.length) { - return true; - } - for (int i = 0; i < markers.length; ++i) { - boolean found = false; - String message = markers[i].getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$ - int severity = markers[i].getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); - for (int j = 0; j < status.length; ++j) { - String msg = status[j].getMessage(); - int cseverity = code2Severity(status[j]); - if (msg.equals(message) && severity == cseverity) { - found = true; - } - } - if (!found) { - return true; - } - } - return false; - } - - int code2Severity(ICModelStatus status) { - int severity; - switch (status.getCode()) { - case ICModelStatusConstants.INVALID_PATHENTRY : - severity = IMarker.SEVERITY_WARNING; - break; - - case ICModelStatusConstants.INVALID_PATH : - severity = IMarker.SEVERITY_WARNING; - break; - - default : - severity = IMarker.SEVERITY_ERROR; - break; - } - - return severity; - } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java new file mode 100644 index 00000000000..66a581d170d --- /dev/null +++ b/core/org.eclipse.cdt.core/model/org/eclipse/cdt/internal/core/model/PathEntryUtil.java @@ -0,0 +1,655 @@ +/******************************************************************************* + * Copyright (c) 2000, 2004 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * QNX Software Systems - Initial API and implementation + *******************************************************************************/ + +package org.eclipse.cdt.internal.core.model; + +import java.io.File; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +import org.eclipse.cdt.core.CCorePlugin; +import org.eclipse.cdt.core.model.CModelException; +import org.eclipse.cdt.core.model.CoreModel; +import org.eclipse.cdt.core.model.CoreModelUtil; +import org.eclipse.cdt.core.model.ICModelMarker; +import org.eclipse.cdt.core.model.ICModelStatus; +import org.eclipse.cdt.core.model.ICModelStatusConstants; +import org.eclipse.cdt.core.model.ICProject; +import org.eclipse.cdt.core.model.IContainerEntry; +import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IIncludeFileEntry; +import org.eclipse.cdt.core.model.ILibraryEntry; +import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IMacroFileEntry; +import org.eclipse.cdt.core.model.IOutputEntry; +import org.eclipse.cdt.core.model.IPathEntry; +import org.eclipse.cdt.core.model.IPathEntryContainer; +import org.eclipse.cdt.core.model.IProjectEntry; +import org.eclipse.cdt.core.model.ISourceEntry; +import org.eclipse.cdt.core.resources.IPathEntryVariableManager; +import org.eclipse.core.resources.IMarker; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IWorkspace; +import org.eclipse.core.resources.IWorkspaceRoot; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IPath; +import org.eclipse.core.runtime.Path; + +public class PathEntryUtil { + + static PathEntryManager manager = PathEntryManager.getDefault(); + static final IMarker[] NO_MARKERS = new IMarker[0]; + + private PathEntryUtil() { + super(); + } + + public static IPathEntry getExpandedPathEntry(IPathEntry entry, ICProject cproject) throws CModelException { + switch (entry.getEntryKind()) { + case IPathEntry.CDT_INCLUDE : { + IIncludeEntry includeEntry = (IIncludeEntry)entry; + IPath refPath = includeEntry.getBaseReference(); + if (refPath != null && !refPath.isEmpty()) { + IPath includePath = includeEntry.getIncludePath(); + if (refPath.isAbsolute()) { + IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(refPath); + if (res != null && res.getType() == IResource.PROJECT) { + IProject project = (IProject)res; + if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) { + ICProject refCProject = CoreModel.getDefault().create(project); + if (refCProject != null) { + IPathEntry[] entries = manager.getResolvedPathEntries(refCProject); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getEntryKind() == IPathEntry.CDT_INCLUDE) { + IIncludeEntry refEntry = (IIncludeEntry)entries[i]; + if (refEntry.getIncludePath().equals(includePath)) { + IPath newBasePath = refEntry.getBasePath(); + // If the includePath is + // relative give a new basepath + // if none + if (!newBasePath.isAbsolute() && !includePath.isAbsolute()) { + IResource refRes; + if (!newBasePath.isEmpty()) { + refRes = cproject.getCModel().getWorkspace().getRoot().findMember( + newBasePath); + } else { + IPath refResPath = refEntry.getPath(); + refRes = cproject.getCModel().getWorkspace().getRoot().findMember( + refResPath); + } + if (refRes != null) { + if (refRes.getType() == IResource.FILE) { + refRes = refRes.getParent(); + } + newBasePath = refRes.getLocation().append(newBasePath); + } + } + return CoreModel.newIncludeEntry(includeEntry.getPath(), newBasePath, includePath); + } + } + } + } + } + } + } else { // Container ref + IPathEntryContainer container = manager.getPathEntryContainer(refPath, cproject); + if (container != null) { + IPathEntry[] entries = container.getPathEntries(); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getEntryKind() == IPathEntry.CDT_INCLUDE) { + IIncludeEntry refEntry = (IIncludeEntry)entries[i]; + if (refEntry.getIncludePath().equals(includePath)) { + IPath newBasePath = refEntry.getBasePath(); + return CoreModel.newIncludeEntry(includeEntry.getPath(), newBasePath, includePath); + } + } + } + } + } + } + break; + } + + case IPathEntry.CDT_MACRO : { + IMacroEntry macroEntry = (IMacroEntry)entry; + IPath refPath = macroEntry.getBaseReference(); + if (refPath != null && !refPath.isEmpty()) { + String name = macroEntry.getMacroName(); + if (refPath.isAbsolute()) { + IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(refPath); + if (res != null && res.getType() == IResource.PROJECT) { + IProject project = (IProject)res; + if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) { + ICProject refCProject = CoreModel.getDefault().create(project); + if (refCProject != null) { + IPathEntry[] entries = manager.getResolvedPathEntries(refCProject); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getEntryKind() == IPathEntry.CDT_MACRO) { + IMacroEntry refEntry = (IMacroEntry)entries[i]; + if (refEntry.getMacroName().equals(name)) { + String value = refEntry.getMacroValue(); + return CoreModel.newMacroEntry(macroEntry.getPath(), name, value); + } + } + } + } + } + } + } else { // Container ref + IPathEntryContainer container = manager.getPathEntryContainer(refPath, cproject); + if (container != null) { + IPathEntry[] entries = container.getPathEntries(); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getEntryKind() == IPathEntry.CDT_MACRO) { + IMacroEntry refEntry = (IMacroEntry)entries[i]; + if (refEntry.getMacroName().equals(name)) { + String value = refEntry.getMacroValue(); + return CoreModel.newMacroEntry(macroEntry.getPath(), name, value); + } + } + } + } + } + } + break; + } + + case IPathEntry.CDT_LIBRARY : { + ILibraryEntry libEntry = (ILibraryEntry)entry; + IPath refPath = libEntry.getBaseReference(); + if (refPath != null && !refPath.isEmpty()) { + IPath libraryPath = libEntry.getLibraryPath(); + if (refPath.isAbsolute()) { + IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(refPath); + if (res != null && res.getType() == IResource.PROJECT) { + IProject project = (IProject)res; + if (CoreModel.hasCNature(project) || CoreModel.hasCCNature(project)) { + ICProject refCProject = CoreModel.getDefault().create(project); + if (refCProject != null) { + IPathEntry[] entries = manager.getResolvedPathEntries(refCProject); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getEntryKind() == IPathEntry.CDT_LIBRARY) { + ILibraryEntry refEntry = (ILibraryEntry)entries[i]; + if (refEntry.getLibraryPath().equals(libraryPath)) { + IPath newBasePath = refEntry.getBasePath(); + // If the libraryPath is + // relative give a new basepath + // if none + if (!newBasePath.isAbsolute() && !libraryPath.isAbsolute()) { + IResource refRes; + if (!newBasePath.isEmpty()) { + refRes = cproject.getCModel().getWorkspace().getRoot().findMember( + newBasePath); + } else { + IPath refResPath = refEntry.getPath(); + refRes = cproject.getCModel().getWorkspace().getRoot().findMember( + refResPath); + } + if (refRes != null) { + if (refRes.getType() == IResource.FILE) { + refRes = refRes.getParent(); + } + newBasePath = refRes.getLocation().append(newBasePath); + } + } + + return CoreModel.newLibraryEntry(entry.getPath(), newBasePath, + refEntry.getLibraryPath(), refEntry.getSourceAttachmentPath(), + refEntry.getSourceAttachmentRootPath(), + refEntry.getSourceAttachmentPrefixMapping(), false); + } + } + } + } + } + } + } else { // Container ref + IPathEntryContainer container = manager.getPathEntryContainer(refPath, cproject); + if (container != null) { + IPathEntry[] entries = container.getPathEntries(); + for (int i = 0; i < entries.length; i++) { + if (entries[i].getEntryKind() == IPathEntry.CDT_LIBRARY) { + ILibraryEntry refEntry = (ILibraryEntry)entries[i]; + if (refEntry.getPath().equals(libraryPath)) { + return CoreModel.newLibraryEntry(entry.getPath(), refEntry.getBasePath(), + refEntry.getLibraryPath(), refEntry.getSourceAttachmentPath(), + refEntry.getSourceAttachmentRootPath(), + refEntry.getSourceAttachmentPrefixMapping(), false); + } + } + } + } + } + } + break; + } + + } + return entry; + } + + public static IPathEntry cloneEntryAndExpand(IPath rpath, IPathEntry entry) { + + // get the path + IPath entryPath = entry.getPath(); + if (entryPath == null) { + entryPath = Path.EMPTY; + } + IPath resourcePath = (entryPath.isAbsolute()) ? entryPath : rpath.append(entryPath); + + IPathEntryVariableManager varManager = CCorePlugin.getDefault().getPathEntryVariableManager(); + switch (entry.getEntryKind()) { + case IPathEntry.CDT_INCLUDE : { + IIncludeEntry include = (IIncludeEntry)entry; + + IPath basePath = include.getBasePath(); + basePath = varManager.resolvePath(basePath); + + IPath includePath = include.getIncludePath(); + includePath = varManager.resolvePath(includePath); + + return CoreModel.newIncludeEntry(resourcePath, basePath, includePath, + include.isSystemInclude(), include.getExclusionPatterns(), include.isExported()); + } + case IPathEntry.CDT_INCLUDE_FILE : { + IIncludeFileEntry includeFile = (IIncludeFileEntry)entry; + + IPath basePath = includeFile.getBasePath(); + basePath = varManager.resolvePath(basePath); + + IPath includeFilePath = includeFile.getIncludeFilePath(); + includeFilePath = varManager.resolvePath(includeFilePath); + + return CoreModel.newIncludeFileEntry(resourcePath, basePath, Path.EMPTY, includeFilePath, + includeFile.getExclusionPatterns(), includeFile.isExported()); + } + case IPathEntry.CDT_LIBRARY : { + ILibraryEntry library = (ILibraryEntry)entry; + + IPath basePath = library.getBasePath(); + basePath = varManager.resolvePath(basePath); + + IPath libraryPath = library.getLibraryPath(); + libraryPath = varManager.resolvePath(libraryPath); + + IPath sourceAttachmentPath = library.getSourceAttachmentPath(); + sourceAttachmentPath = varManager.resolvePath(sourceAttachmentPath); + + IPath sourceAttachmentRootPath = library.getSourceAttachmentRootPath(); + sourceAttachmentRootPath = varManager.resolvePath(sourceAttachmentRootPath); + + IPath sourceAttachmentPrefixMapping = library.getSourceAttachmentPrefixMapping(); + sourceAttachmentPrefixMapping = varManager.resolvePath(sourceAttachmentPrefixMapping); + + return CoreModel.newLibraryEntry(resourcePath, basePath, libraryPath, + sourceAttachmentPath, sourceAttachmentRootPath, + sourceAttachmentPrefixMapping, library.isExported()); + } + case IPathEntry.CDT_MACRO : { + IMacroEntry macro = (IMacroEntry)entry; + return CoreModel.newMacroEntry(resourcePath, macro.getMacroName(), macro.getMacroValue(), + macro.getExclusionPatterns(), macro.isExported()); + } + case IPathEntry.CDT_MACRO_FILE : { + IMacroFileEntry macroFile = (IMacroFileEntry)entry; + + IPath basePath = macroFile.getBasePath(); + basePath = varManager.resolvePath(basePath); + + IPath macroFilePath = macroFile.getMacroFilePath(); + macroFilePath = varManager.resolvePath(macroFilePath); + + return CoreModel.newMacroFileEntry(resourcePath, basePath, Path.EMPTY, macroFilePath, + macroFile.getExclusionPatterns(), macroFile.isExported()); + } + case IPathEntry.CDT_OUTPUT : { + IOutputEntry out = (IOutputEntry)entry; + return CoreModel.newOutputEntry(resourcePath, out.getExclusionPatterns()); + } + case IPathEntry.CDT_PROJECT : { + IProjectEntry projEntry = (IProjectEntry)entry; + return CoreModel.newProjectEntry(projEntry.getPath(), projEntry.isExported()); + } + case IPathEntry.CDT_SOURCE : { + ISourceEntry source = (ISourceEntry)entry; + return CoreModel.newSourceEntry(resourcePath, source.getExclusionPatterns()); + } + case IPathEntry.CDT_CONTAINER : { + return CoreModel.newContainerEntry(entry.getPath(), entry.isExported()); + } + } + return entry; + } + + public static ICModelStatus validatePathEntry(ICProject cProject, IPathEntry[] entries) { + + // Check duplication. + for (int i = 0; i < entries.length; i++) { + IPathEntry entry = entries[i]; + if (entry == null) { + continue; + } + for (int j = 0; j < entries.length; j++) { + IPathEntry otherEntry = entries[j]; + if (otherEntry == null) { + continue; + } + if (entry != otherEntry && otherEntry.equals(entry)) { + StringBuffer errMesg = new StringBuffer(CCorePlugin.getResourceString("CoreModel.PathEntry.DuplicateEntry")); //$NON-NLS-1$ + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); + } + } + } + + // check duplication of sources + List dups = checkForDuplication(Arrays.asList(entries), IPathEntry.CDT_SOURCE); + if (dups.size() > 0) { + ICModelStatus[] cmodelStatus = new ICModelStatus[dups.size()]; + for (int i = 0; i < dups.size(); ++i) { + StringBuffer errMesg = new StringBuffer(CCorePlugin.getResourceString("CoreModel.PathEntry.DuplicateEntry")); //$NON-NLS-1$ + cmodelStatus[i] = new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); + } + return CModelStatus.newMultiStatus(ICModelStatusConstants.INVALID_PATHENTRY, cmodelStatus); + } + + // check duplication of Outputs + dups = checkForDuplication(Arrays.asList(entries), IPathEntry.CDT_OUTPUT); + if (dups.size() > 0) { + ICModelStatus[] cmodelStatus = new ICModelStatus[dups.size()]; + for (int i = 0; i < dups.size(); ++i) { + StringBuffer errMesg = new StringBuffer(CCorePlugin.getResourceString("CoreModel.PathEntry.DuplicateEntry")); //$NON-NLS-1$ + cmodelStatus[i] = new CModelStatus(ICModelStatusConstants.NAME_COLLISION, errMesg.toString()); + } + return CModelStatus.newMultiStatus(ICModelStatusConstants.INVALID_PATHENTRY, cmodelStatus); + } + + // allow nesting source entries in each other as long as the outer entry + // excludes the inner one + for (int i = 0; i < entries.length; i++) { + IPathEntry entry = entries[i]; + if (entry == null) { + continue; + } + IPath entryPath = entry.getPath(); + int kind = entry.getEntryKind(); + if (kind == IPathEntry.CDT_SOURCE) { + for (int j = 0; j < entries.length; j++) { + IPathEntry otherEntry = entries[j]; + if (otherEntry == null) { + continue; + } + int otherKind = otherEntry.getEntryKind(); + IPath otherPath = otherEntry.getPath(); + if (entry != otherEntry && (otherKind == IPathEntry.CDT_SOURCE)) { + char[][] exclusionPatterns = ((ISourceEntry)otherEntry).fullExclusionPatternChars(); + if (otherPath.isPrefixOf(entryPath) && !otherPath.equals(entryPath) + && !CoreModelUtil.isExcluded(entryPath.append("*"), exclusionPatterns)) { //$NON-NLS-1$ + + String exclusionPattern = entryPath.removeFirstSegments(otherPath.segmentCount()).segment(0); + if (CoreModelUtil.isExcluded(entryPath, exclusionPatterns)) { + StringBuffer errMesg = new StringBuffer( + CCorePlugin.getResourceString("CoreModel.PathEntry.NestedEntry")); //$NON-NLS-1$ + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); + } else if (otherKind == IPathEntry.CDT_SOURCE) { + exclusionPattern += '/'; + StringBuffer errMesg = new StringBuffer( + CCorePlugin.getResourceString("CoreModel.PathEntry.NestedEntry")); //$NON-NLS-1$ + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); + } else { + StringBuffer errMesg = new StringBuffer( + CCorePlugin.getResourceString("CoreModel.PathEntry.NestedEntry")); //$NON-NLS-1$ + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, errMesg.toString()); //$NON-NLS-1$ + } + } + } + } + } + } + + return CModelStatus.VERIFIED_OK; + } + + public static ICModelStatus validatePathEntry(ICProject cProject, IPathEntry entry, boolean checkSourceAttachment, + boolean recurseInContainers) { + IProject project = cProject.getProject(); + IPath path = entry.getPath(); + if (entry.getEntryKind() != IPathEntry.CDT_PROJECT) { + if (!isValidWorkspacePath(project, path)) { + return new CModelStatus( + ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.0") + path.toOSString() + " for " + ((PathEntry)entry).getKindString()); //$NON-NLS-1$ //$NON-NLS-2$ + } + } + + switch (entry.getEntryKind()) { + case IPathEntry.CDT_INCLUDE : { + IIncludeEntry include = (IIncludeEntry)entry; + IPath includePath = include.getFullIncludePath(); + if (!isValidExternalPath(includePath)) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.2") + " (" + includePath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } + if (!isValidBasePath(include.getBasePath())) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.1") + " (" + includePath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } + break; + } + case IPathEntry.CDT_LIBRARY : { + ILibraryEntry library = (ILibraryEntry)entry; + if (checkSourceAttachment) { + IPath sourceAttach = library.getSourceAttachmentPath(); + if (sourceAttach != null) { + if (!sourceAttach.isAbsolute()) { + if (!isValidWorkspacePath(project, sourceAttach) || !isValidExternalPath(sourceAttach)) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.3") + " (" + sourceAttach.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$ + } + } + } + } + IPath libraryPath = library.getFullLibraryPath(); + if (!isValidExternalPath(libraryPath)) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.4") + " (" + libraryPath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } + if (!isValidBasePath(library.getBasePath())) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.7") + " (" + libraryPath.toOSString() + ")"); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$ + } + break; + } + case IPathEntry.CDT_PROJECT : { + IProjectEntry projEntry = (IProjectEntry)entry; + path = projEntry.getPath(); + IProject reqProject = project.getWorkspace().getRoot().getProject(path.segment(0)); + if (!reqProject.isAccessible()) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.5")); //$NON-NLS-1$ + } + if (! (CoreModel.hasCNature(reqProject) || CoreModel.hasCCNature(reqProject))) { + return new CModelStatus(ICModelStatusConstants.INVALID_PATHENTRY, + CoreModelMessages.getString("PathEntryManager.6")); //$NON-NLS-1$ + } + break; + } + case IPathEntry.CDT_CONTAINER : + if (recurseInContainers) { + try { + IPathEntryContainer cont = manager.getPathEntryContainer((IContainerEntry)entry, cProject); + IPathEntry[] contEntries = cont.getPathEntries(); + for (int i = 0; i < contEntries.length; i++) { + ICModelStatus status = validatePathEntry(cProject, contEntries[i], checkSourceAttachment, false); + if (!status.isOK()) { + return status; + } + } + } catch (CModelException e) { + return new CModelStatus(e); + } + } + break; + } + return CModelStatus.VERIFIED_OK; + } + + private static boolean isValidWorkspacePath(IProject project, IPath path) { + if (path == null) { + return false; + } + IWorkspaceRoot workspaceRoot = project.getWorkspace().getRoot(); + // We accept empy path as the project + IResource res = null; + if (path.isAbsolute()) { + res = workspaceRoot.findMember(path); + } else { + res = project.findMember(path); + } + return (res != null && res.isAccessible()); + } + + private static boolean isValidExternalPath(IPath path) { + if (path != null) { + File file = path.toFile(); + if (file != null) { + return file.exists(); + } + } + return false; + } + + private static boolean isValidBasePath(IPath path) { + if (!path.isEmpty() && !path.isAbsolute()) { + IResource res = ResourcesPlugin.getWorkspace().getRoot().findMember(path); + if (res == null || !res.isAccessible()) { + return false; + } + } + return true; + } + + public static List checkForDuplication(List pathEntries, int type) { + List duplicate = new ArrayList(pathEntries.size()); + for (int i = 0; i < pathEntries.size(); ++i) { + IPathEntry pathEntry = (IPathEntry)pathEntries.get(i); + if (pathEntry.getEntryKind() == type) { + for (int j = 0; j < pathEntries.size(); ++j) { + IPathEntry otherEntry = (IPathEntry)pathEntries.get(j); + if (otherEntry.getEntryKind() == type) { + if (!pathEntry.equals(otherEntry)) { + if (!duplicate.contains(pathEntry)) { + if (pathEntry.getPath().equals(otherEntry.getPath())) { + // duplication of sources + duplicate.add(otherEntry); + } + } + } + } + } + } + } + return duplicate; + } + + /** + * Record a new marker denoting a pathentry problem + */ + public static void createPathEntryProblemMarker(IProject project, ICModelStatus status) { + int severity = code2Severity(status); + try { + IMarker marker = project.createMarker(ICModelMarker.PATHENTRY_PROBLEM_MARKER); + marker.setAttributes(new String[]{IMarker.MESSAGE, IMarker.SEVERITY, IMarker.LOCATION, + ICModelMarker.PATHENTRY_FILE_FORMAT,}, new Object[]{status.getMessage(), new Integer(severity), "pathentry",//$NON-NLS-1$ + "false",//$NON-NLS-1$ + }); + } catch (CoreException e) { + // could not create marker: cannot do much + //e.printStackTrace(); + } + } + + /** + * Remove all markers denoting pathentry problems + */ + public static void flushPathEntryProblemMarkers(IProject project) { + IWorkspace workspace = project.getWorkspace(); + + try { + IMarker[] markers = getPathEntryProblemMarkers(project); + workspace.deleteMarkers(markers); + } catch (CoreException e) { + // could not flush markers: not much we can do + //e.printStackTrace(); + } + } + + /** + * get all markers denoting pathentry problems + */ + public static IMarker[] getPathEntryProblemMarkers(IProject project) { + + try { + IMarker[] markers = project.findMarkers(ICModelMarker.PATHENTRY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); + if (markers != null) { + return markers; + } + } catch (CoreException e) { + //e.printStackTrace(); + } + return NO_MARKERS; + } + + public static boolean hasPathEntryProblemMarkersChange(IProject project, ICModelStatus[] status) { + IMarker[] markers = getPathEntryProblemMarkers(project); + if (markers.length != status.length) { + return true; + } + for (int i = 0; i < markers.length; ++i) { + boolean found = false; + String message = markers[i].getAttribute(IMarker.MESSAGE, ""); //$NON-NLS-1$ + int severity = markers[i].getAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR); + for (int j = 0; j < status.length; ++j) { + String msg = status[j].getMessage(); + int cseverity = code2Severity(status[j]); + if (msg.equals(message) && severity == cseverity) { + found = true; + } + } + if (!found) { + return true; + } + } + return false; + } + + public static int code2Severity(ICModelStatus status) { + int severity; + switch (status.getCode()) { + case ICModelStatusConstants.INVALID_PATHENTRY : + severity = IMarker.SEVERITY_WARNING; + break; + + case ICModelStatusConstants.INVALID_PATH : + severity = IMarker.SEVERITY_WARNING; + break; + + default : + severity = IMarker.SEVERITY_ERROR; + break; + } + + return severity; + } + +} diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java index 2deff06ce40..413fbac83b0 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerInfo.java @@ -13,17 +13,24 @@ package org.eclipse.cdt.core.resources; import java.util.Collections; import java.util.Map; -import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.parser.IExtendedScannerInfo; -public class ScannerInfo implements IScannerInfo { +public class ScannerInfo implements IExtendedScannerInfo { - private final Map macroMap; - private final String[] includePaths; + private final Map fMacroMap; + private final String[] fSystemIncludePaths; + private final String[] fMacroFiles; + private final String[] fIncludeFiles; + private final String[] fLocalIncludePaths; final static String[] EMPTY_ARRAY_STRING = new String[0]; - protected ScannerInfo(String[] includePaths, Map macroMap) { - this.includePaths = includePaths; - this.macroMap = macroMap; + protected ScannerInfo(String[] systemIncludePaths, String[] localIncludePaths, String[] includeFiles, + Map macroMap, String[] macroFiles) { + fSystemIncludePaths = (systemIncludePaths == null) ? EMPTY_ARRAY_STRING : systemIncludePaths; + fLocalIncludePaths = (localIncludePaths == null) ? EMPTY_ARRAY_STRING : localIncludePaths; + fIncludeFiles = (includeFiles == null) ? EMPTY_ARRAY_STRING : includeFiles; + fMacroFiles = (macroFiles == null) ? EMPTY_ARRAY_STRING : macroFiles; + fMacroMap = (macroMap == null) ? Collections.EMPTY_MAP : macroMap; } /* @@ -32,10 +39,7 @@ public class ScannerInfo implements IScannerInfo { * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() */ public synchronized String[] getIncludePaths() { - if (includePaths == null) { - return EMPTY_ARRAY_STRING; - } - return includePaths; + return fSystemIncludePaths; } /* @@ -44,10 +48,19 @@ public class ScannerInfo implements IScannerInfo { * @see org.eclipse.cdt.core.build.managed.IScannerInfo#getIncludePaths() */ public synchronized Map getDefinedSymbols() { - if (macroMap == null) { - return Collections.EMPTY_MAP; - } - return macroMap; + return fMacroMap; + } + + public String[] getMacroFiles() { + return fMacroFiles; + } + + public String[] getIncludeFiles() { + return fIncludeFiles; + } + + public String[] getLocalIncludePath() { + return fLocalIncludePaths; } } diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java index ee36acce6da..43a60f902b0 100644 --- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java +++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/core/resources/ScannerProvider.java @@ -23,7 +23,9 @@ import org.eclipse.cdt.core.model.ICElement; import org.eclipse.cdt.core.model.ICElementDelta; import org.eclipse.cdt.core.model.IElementChangedListener; import org.eclipse.cdt.core.model.IIncludeEntry; +import org.eclipse.cdt.core.model.IIncludeFileEntry; import org.eclipse.cdt.core.model.IMacroEntry; +import org.eclipse.cdt.core.model.IMacroFileEntry; import org.eclipse.cdt.core.parser.IScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; import org.eclipse.cdt.core.parser.IScannerInfoProvider; @@ -84,21 +86,51 @@ public class ScannerProvider extends AbstractCExtension implements IScannerInfoP IPath resPath = resource.getFullPath(); try { + // get the includes IIncludeEntry[] includeEntries = CoreModel.getIncludeEntries(resPath); - String[] includes = new String[includeEntries.length]; - for (int i = 0; i < includes.length; ++i) { - includes[i] = includeEntries[i].getFullIncludePath().toOSString(); + int localCount = 0, systemCount = 0; + for (int i = 0; i < includeEntries.length; ++i) { + if (includeEntries[i].isSystemInclude()) { + ++systemCount; + } else { + ++localCount; + } } + String[] localIncludes = new String[localCount]; + String[] systemIncludes = new String[systemCount]; + for (int i = 0; i < includeEntries.length; ++i) { + if (includeEntries[i].isSystemInclude()) { + systemIncludes[i] = includeEntries[i].getFullIncludePath().toOSString(); + } else { + localIncludes[i] = includeEntries[i].getFullIncludePath().toOSString(); + } + } + + // get the includeFile + IIncludeFileEntry[] includeFileEntries = CoreModel.getIncludeFileEntries(resPath); + String[] includeFiles = new String[includeFileEntries.length]; + for (int i = 0; i < includeFiles.length; ++i) { + includeFiles[i] = includeFileEntries[i].getFullIncludeFilePath().toOSString(); + } + + // get the macros IMacroEntry[] macros = CoreModel.getMacroEntries(resPath); Map symbolMap = new HashMap(); for (int i = 0; i < macros.length; ++i) { symbolMap.put(macros[i].getMacroName(), macros[i].getMacroValue()); } - return new ScannerInfo(includes, symbolMap); + + // get the macro files + IMacroFileEntry[] macroFileEntries = CoreModel.getMacroFileEntries(resPath); + String[] macroFiles = new String[macroFileEntries.length]; + for (int i = 0; i < macroFiles.length; ++i) { + macroFiles[i] = macroFileEntries[i].getFullMacroFilePath().toOSString(); + } + return new ScannerInfo(systemIncludes, localIncludes, includeFiles, symbolMap, macroFiles); } catch (CModelException e) { // } - return new ScannerInfo(null, null); + return new ScannerInfo(null, null, null, null, null); } /*