Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] Analysis and solutions for Open Declaration/Definition: case-senstiive path checks on Win32

Title: Analysis and solutions for Open Declaration/Definition: case-senstiive path checks on Win32

The first bug I ran across is simple but devastating.  IncludeEntry sometimes stores include paths in a slightly different case than the paths the indexer constructs.  (Why?  I didn't find out yet.)  Due to some parts of Eclipse's Path implementation being case-sensitive on all platforms -- esp. in #isPrefixOf() -- IncludeReference#isOnIncludeEntry() fails to detect that a file is on the include paths.

So the indexer could have totally complete and correct data, but CModelManager#createTranslationUnitFrom() would fail to create a TU for the file.  (There seem to be other problems with this method due to the lack of a fallback or any notification when trying to construct a TU for a non-includeable file.) 

It's simpler not to touch Path or uses of #isPrefixOf(), so my solution is to store a canonical path in IncludeEntry and canonicalize the input path on entry to IncludeReference#isOnIncludeEntry().  My quick'n'dirty "canonicalization" just lowercases paths when on the Win32 platform, though going through would be best (and would preserve the case displayed in the UI), though with an unknown performance hit.   I didn't search for other places where this might be a problem.

        public IncludeEntry(IPath resourcePath, IPath basePath, IPath baseRef, IPath includePath, boolean isSystemInclude,

                        IPath[] exclusionPatterns, boolean isExported) {
                super(IPathEntry.CDT_INCLUDE, basePath, baseRef, resourcePath, exclusionPatterns, isExported);
                this.includePath = (includePath == null) ? Path.EMPTY :
                this.isSystemInclude = isSystemInclude;


        /* (non-Javadoc)
         * @see org.eclipse.cdt.core.model.IIncludeReference#isOnIncludeEntry(org.eclipse.core.runtime.IPath)
        public boolean isOnIncludeEntry(IPath path) {
                path = Util.getCanonicalPath(path);
                if (fIncludeEntry.getIncludePath().isPrefixOf(path)
                                && !CoreModelUtil.isExcluded(path, fIncludeEntry.fullExclusionPatternChars())) {
                        return true;
                return false;


        private static boolean hasCaseInsensitiveFileSystem;
        static {
                hasCaseInsensitiveFileSystem = Platform.getOS().equals(Platform.OS_WIN32);

         * Get a canonical IPath, for use in IPath#isPrefixOf, #equals, etc.
         * to overcome a bug in Path that doesn't account for
         * case-insensitive filesystems.
        public static IPath getCanonicalPath(IPath path) {
                if (hasCaseInsensitiveFileSystem) {
                        // be stupid for now (instead of using File#toCanonicalFile())
                        return new Path(path.toOSString().toLowerCase());
                return path;

-- Ed

Back to the top