Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-patch] OpenInclude - Search Local Includes

Folks,

  This is an updated patch for the OpenIncludeAction which hangs
off of the Outline View.  Unlike last time this one tries to stick
to the "your project should be configured properly" consistancy
rules =;-)

  The current version will not search the directory location of the
current file for local "" include files.  This patch always searches
the local directory, but has a provision for doing the correct thing
when I figure out what the correct way to get an Include from an
ICElement (see post in cdt-dev/core) =;-)

  Additionally this patch still includes the more efficient search 
of the local project for when there is no scanner information provided.
This will all get rolled into the scanner class so that we all have
a common location for getting at these things, but for now this is a
small patch to address PR 51355.

For the ChangeLog

- Add the local directory as part of the include paths for local 
  include statements.  PR 51355


Index: src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java
===================================================================
RCS file: /home/tools/org.eclipse.cdt.ui/src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java,v
retrieving revision 1.7
diff -u -r1.7 OpenIncludeAction.java
--- src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java	28 Aug 2003 19:47:01 -0000	1.7
+++ src/org/eclipse/cdt/internal/ui/editor/OpenIncludeAction.java	15 Feb 2004 09:34:07 -0000
@@ -23,6 +23,8 @@
 import org.eclipse.core.resources.IFile;
 import org.eclipse.core.resources.IProject;
 import org.eclipse.core.resources.IResource;
+import org.eclipse.core.resources.IResourceProxy;
+import org.eclipse.core.resources.IResourceProxyVisitor;
 import org.eclipse.core.resources.ResourcesPlugin;
 import org.eclipse.core.runtime.CoreException;
 import org.eclipse.core.runtime.IPath;
@@ -65,6 +67,14 @@
 		if (include == null) {
 			return;
 		}
+
+		/* FIXME 
+		 * The information about whether this is a local include file or not
+		 * a local include file is in the Include specific ICElement.  Unfortunately
+		 * while we know that, it isn't part of the public interface.  For now we
+		 * just assume that every header has the possibility of being local.
+		 */
+		boolean isLocal = true;
 		
 		try {
 			IResource res = include.getUnderlyingResource();
@@ -81,10 +91,18 @@
 						info = provider.getScannerInformation(proj);
 					}
 					if (info != null) {
+						//If the header is local, then look in the current location first
 						String[] includePaths = info.getIncludePaths();
+
+						if(isLocal) {		//Prepend our path at the start of this array
+							String [] newIncludePaths = new String[includePaths.length + 1];
+							newIncludePaths[0] = res.getLocation().removeLastSegments(1).toOSString();
+							System.arraycopy(includePaths, 0, newIncludePaths, 1, includePaths.length);			
+							includePaths = newIncludePaths;
+						}
+						
 						findFile(includePaths, includeName, filesFound);
 					} else {
						// Fall back and search the project
 						findFile(proj, new Path(includeName), filesFound);
 					}
 				}
@@ -115,27 +133,76 @@
 		}
 	}
 
-	private void findFile(String[] includePaths,  String name, ArrayList list)  throws CoreException {
+	private void findFile(String[] includePaths, String name, ArrayList list)  throws CoreException {		
 		for (int i = 0; i < includePaths.length; i++) {
 			IPath path = new Path(includePaths[i] + "/" + name);
 			File file = path.toFile();
-			if (file.exists()) {
+			if (file.exists() && !list.contains(path)) {
 				list.add(path);
 			} 
 		}
 	}
 
-	private void findFile(IContainer parent, IPath name, ArrayList list) throws CoreException {
-		IResource found= parent.findMember(name);
-		if (found != null && found.getType() == IResource.FILE) {
-			list.add(found.getLocation());
+	private void findFile(IContainer parent, IPath name, final ArrayList list) throws CoreException {
+		final String lastSegment = name.lastSegment();
+		if(lastSegment == null) {
+			return;
 		}
-		IResource[] children= parent.members();
-		for (int i= 0; i < children.length; i++) {
-			if (children[i] instanceof IContainer) {
-				findFile((IContainer)children[i], name, list);
+
+		final IPath pathSegments = name.removeLastSegments(1);
+		
+		//We use the lastSegment as a fast key, but then make sure that we can match
+		//the rest of the segments (if they exist) so a path like:
+		//#include "subsystem/includefile.h" won't match with "a/b/c/includefile.h"
+		IResourceProxyVisitor visitor = new IResourceProxyVisitor() {
+			private boolean checkSegments(IPath sourceSegments, IPath targetSegments) {
+				if(sourceSegments == null) {
+					return true;
+				}
+				if(targetSegments == null) {
+					return false;
+				}
+				
+				int segmentCount = sourceSegments.segmentCount();
+				int targetCount = targetSegments.segmentCount();
+				if(segmentCount > targetCount) {
+					return false;
+				}
+				
+				for(int i = segmentCount - 1; i >= 0; i--) {
+					if(!sourceSegments.segment(i).equals(targetSegments.segment(--targetCount))) {
+						return false;
+					}	
+				}
+				
+				return true;
+			}
+			
+			public boolean visit(IResourceProxy proxy) throws CoreException {
+				String resourceName = proxy.getName();
+				if(resourceName.equals(lastSegment)) {
+					IResource res = proxy.requestResource();
+					if(!res.exists()) {
+						return true;
+					}
+					
+					IPath location = res.getLocation();
+					if(list.contains(location)) {
+						return true;
+					}
+
+					//Check segment match criteria to make sure we really match this entry
+					if(checkSegments(pathSegments, location.removeLastSegments(1)) != true) {
+						return true;
+					} 
+					
+					list.add(location);
+				}
+				return true;
 			}
-		}		
+		};
+		
+		parent.accept(visitor, IResource.NONE);		
 	}
 

Back to the top