~ubuntu-branches/debian/sid/eclipse-cdt/sid

« back to all changes in this revision

Viewing changes to core/org.eclipse.cdt.core/utils/org/eclipse/cdt/utils/PathUtil.java

  • Committer: Package Import Robot
  • Author(s): Jakub Adam
  • Date: 2011-10-06 21:15:04 UTC
  • mfrom: (1.1.4)
  • Revision ID: package-import@ubuntu.com-20111006211504-8dutmljjih0zikfv
Tags: 8.0.1-1
* New upstream release.
* Split the JNI packages into a separate architecture dependent
  package and made eclipse-cdt architecture independent.
* Install JNI libraries into multiarch aware location
* Bumped Standards-Version to 3.9.2.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*******************************************************************************
 
2
 * Copyright (c) 2004, 2011 QNX Software Systems and others.
 
3
 * All rights reserved. This program and the accompanying materials
 
4
 * are made available under the terms of the Eclipse Public License v1.0
 
5
 * which accompanies this distribution, and is available at
 
6
 * http://www.eclipse.org/legal/epl-v10.html
 
7
 *
 
8
 * Contributors:
 
9
 *     QNX Software Systems - initial API and implementation
 
10
 *     Markus Schorn (Wind River Systems)
 
11
 *     Ed Swartz (Nokia)
 
12
 *     Sergey Prigogin (Google)
 
13
 *     James Blackburn (Broadcom Corp.)
 
14
 *******************************************************************************/
 
15
package org.eclipse.cdt.utils;
 
16
 
 
17
import java.io.File;
 
18
import java.io.IOException;
 
19
 
 
20
import org.eclipse.cdt.core.CCorePlugin;
 
21
import org.eclipse.cdt.core.parser.IScannerInfo;
 
22
import org.eclipse.cdt.core.parser.IScannerInfoProvider;
 
23
import org.eclipse.core.resources.IProject;
 
24
import org.eclipse.core.resources.IResource;
 
25
import org.eclipse.core.resources.IWorkspace;
 
26
import org.eclipse.core.resources.IWorkspaceRoot;
 
27
import org.eclipse.core.resources.ResourcesPlugin;
 
28
import org.eclipse.core.runtime.Assert;
 
29
import org.eclipse.core.runtime.IPath;
 
30
import org.eclipse.core.runtime.Path;
 
31
import org.eclipse.core.runtime.Platform;
 
32
 
 
33
/**
 
34
 * @noextend This class is not intended to be subclassed by clients.
 
35
 * @noinstantiate This class is not intended to be instantiated by clients.
 
36
 */
 
37
public class PathUtil {
 
38
        /** Detect whether we're running on Windows (as IPath does) */
 
39
        private static final boolean WINDOWS = java.io.File.separatorChar == '\\';
 
40
 
 
41
        public static boolean isWindowsFileSystem() {
 
42
                return WINDOWS;
 
43
        }
 
44
 
 
45
        public static IWorkspaceRoot getWorkspaceRoot() {
 
46
                IWorkspace workspace = ResourcesPlugin.getWorkspace();
 
47
                if (workspace != null) {
 
48
                        return workspace.getRoot();
 
49
                }
 
50
                return null;
 
51
        }
 
52
 
 
53
        /**
 
54
         * Return the canonical path (or the passed in path, if one couldn't be found).
 
55
         * @param fullPath
 
56
         * @return canonicalized IPath or passed in fullPath.
 
57
         */
 
58
        public static IPath getCanonicalPath(IPath fullPath) {
 
59
                if (!fullPath.isAbsolute())
 
60
                        return fullPath;
 
61
                
 
62
            File file = fullPath.toFile();
 
63
                try {
 
64
                        String canonPath = file.getCanonicalPath();
 
65
                        IPath canonicalPath = new Path(canonPath);
 
66
                        if (fullPath.getDevice() == null)
 
67
                                canonicalPath = canonicalPath.setDevice(null);
 
68
                        return canonicalPath;
 
69
                } catch (IOException ex) {
 
70
                }
 
71
                return fullPath;
 
72
        }
 
73
 
 
74
        /**
 
75
         * On Windows discover the {@link java.io.File#getCanonicalPath()} for
 
76
         * a given absolute path.
 
77
         * On other platforms, and for relative paths returns the passed in fullPath
 
78
         * @param fullPath
 
79
         * @return canonicalized IPath or passed in fullPath.
 
80
         * @since 5.3
 
81
         */
 
82
        public static IPath getCanonicalPathWindows(IPath fullPath) {
 
83
                if (!WINDOWS)
 
84
                        return fullPath;
 
85
                return getCanonicalPath(fullPath);
 
86
        }
 
87
 
 
88
        public static IPath getWorkspaceRelativePath(IPath fullPath) {
 
89
                IWorkspaceRoot workspaceRoot = getWorkspaceRoot();
 
90
                if (workspaceRoot != null) {
 
91
                        IPath workspaceLocation = workspaceRoot.getLocation();
 
92
                        if (workspaceLocation != null && isPrefix(workspaceLocation, fullPath)) {
 
93
                                int segments = matchingFirstSegments(fullPath, workspaceLocation);
 
94
                                IPath relPath = fullPath.setDevice(null).removeFirstSegments(segments);
 
95
                                return new Path("").addTrailingSeparator().append(relPath); //$NON-NLS-1$
 
96
                        }
 
97
                }
 
98
                return fullPath;
 
99
        }
 
100
        
 
101
        public static IPath getProjectRelativePath(IPath fullPath, IProject project) {
 
102
                IPath projectPath = project.getFullPath();
 
103
                if (isPrefix(projectPath, fullPath)) {
 
104
                        return fullPath.removeFirstSegments(projectPath.segmentCount());
 
105
                }
 
106
                projectPath = project.getLocation();
 
107
                if (isPrefix(projectPath, fullPath)) {
 
108
                        return fullPath.removeFirstSegments(projectPath.segmentCount());
 
109
                }
 
110
                return getWorkspaceRelativePath(fullPath);
 
111
        }
 
112
 
 
113
        public static IPath getWorkspaceRelativePath(String fullPath) {
 
114
                return getWorkspaceRelativePath(new Path(fullPath));
 
115
        }
 
116
 
 
117
        public static IPath getRawLocation(IPath wsRelativePath) {
 
118
                IWorkspaceRoot workspaceRoot = getWorkspaceRoot();
 
119
                if (workspaceRoot != null && wsRelativePath != null) {
 
120
                        IPath workspaceLocation = workspaceRoot.getLocation();
 
121
                        if (workspaceLocation != null && !isPrefix(workspaceLocation, wsRelativePath)) {
 
122
                                return workspaceLocation.append(wsRelativePath);
 
123
                        }
 
124
                }
 
125
                return wsRelativePath;
 
126
        }
 
127
 
 
128
    public static IPath makeRelativePath(IPath path, IPath relativeTo) {
 
129
        int segments = matchingFirstSegments(relativeTo, path);
 
130
        if (segments > 0) {
 
131
            IPath prefix = relativeTo.removeFirstSegments(segments);
 
132
            IPath suffix = path.removeFirstSegments(segments);
 
133
            IPath relativePath = new Path(""); //$NON-NLS-1$
 
134
            for (int i = 0; i < prefix.segmentCount(); ++i) {
 
135
                relativePath = relativePath.append(".." + IPath.SEPARATOR); //$NON-NLS-1$
 
136
            }
 
137
            return relativePath.append(suffix);
 
138
        }
 
139
        return null;
 
140
    }
 
141
 
 
142
    public static IPath makeRelativePathToProjectIncludes(IPath fullPath, IProject project) {
 
143
        IScannerInfoProvider provider = CCorePlugin.getDefault().getScannerInfoProvider(project);
 
144
        if (provider != null) {
 
145
            IScannerInfo info = provider.getScannerInformation(project);
 
146
            if (info != null) {
 
147
                return makeRelativePathToIncludes(fullPath, info.getIncludePaths());
 
148
            }
 
149
        }
 
150
        return null;
 
151
    }
 
152
    
 
153
    public static IPath makeRelativePathToIncludes(IPath fullPath, String[] includePaths) {
 
154
        IPath relativePath = null;
 
155
        int mostSegments = 0;
 
156
        for (int i = 0; i < includePaths.length; ++i) {
 
157
            IPath includePath = new Path(includePaths[i]);
 
158
            if (isPrefix(includePath, fullPath)) {
 
159
                int segments = includePath.segmentCount();
 
160
                if (segments > mostSegments) {
 
161
                    relativePath = fullPath.removeFirstSegments(segments).setDevice(null);
 
162
                    mostSegments = segments;
 
163
                }
 
164
            }
 
165
        }
 
166
        return relativePath;
 
167
    }
 
168
 
 
169
    public static IProject getEnclosingProject(IPath fullPath) {
 
170
                IWorkspaceRoot root = getWorkspaceRoot();
 
171
                if (root != null) {
 
172
                        IPath path = getWorkspaceRelativePath(fullPath);
 
173
                        while (path.segmentCount() > 0) {
 
174
                                IResource res = root.findMember(path);
 
175
                                if (res != null)
 
176
                                    return res.getProject();
 
177
 
 
178
                                path = path.removeLastSegments(1);
 
179
                        }
 
180
                }
 
181
                return null;
 
182
    }
 
183
    
 
184
    public static IPath getValidEnclosingFolder(IPath fullPath) {
 
185
                IWorkspaceRoot root = getWorkspaceRoot();
 
186
                if (root != null) {
 
187
                        IPath path = getWorkspaceRelativePath(fullPath);
 
188
                        while (path.segmentCount() > 0) {
 
189
                                IResource res = root.findMember(path);
 
190
                                if (res != null && res.exists() && (res.getType() == IResource.PROJECT || res.getType() == IResource.FOLDER))
 
191
                                    return path;
 
192
 
 
193
                                path = path.removeLastSegments(1);
 
194
                        }
 
195
                }
 
196
                return null;
 
197
        }
 
198
 
 
199
    /**
 
200
         * Checks whether path1 is the same as path2.
 
201
         * @return <code>true</code> if path1 is the same as path2, and <code>false</code> otherwise
 
202
     * 
 
203
     * Similar to IPath.equals(Object obj), but takes case sensitivity of the file system
 
204
     * into account.
 
205
     * @since 5.1
 
206
     * @deprecated Use {@link #equalPath(IPath, IPath)} instead.
 
207
     */
 
208
        @Deprecated
 
209
        public boolean equal(IPath path1, IPath path2) {
 
210
                // Check leading separators
 
211
                if (path1.isAbsolute() != path2.isAbsolute() || path1.isUNC() != path2.isUNC()) {
 
212
                        return false;
 
213
                }
 
214
                int i = path1.segmentCount();
 
215
                // Check segment count
 
216
                if (i != path2.segmentCount())
 
217
                        return false;
 
218
                // Check segments in reverse order - later segments more likely to differ
 
219
                while (--i >= 0) {
 
220
                        if (!path1.segment(i).equals(path2.segment(i)))
 
221
                                return false;
 
222
                }
 
223
                // Check device last (least likely to differ)
 
224
                if (path1.getDevice() == null) {
 
225
                        return path2.getDevice() == null;
 
226
                } else {
 
227
                        return path1.getDevice().equalsIgnoreCase(path2.getDevice());
 
228
                }
 
229
        }
 
230
 
 
231
    /**
 
232
         * Checks whether path1 is the same as path2.
 
233
         * @return <code>true</code> if path1 is the same as path2, and <code>false</code> otherwise
 
234
     * 
 
235
     * Similar to IPath.equals(Object obj), but takes case sensitivity of the file system
 
236
     * into account.
 
237
     * @since 5.3
 
238
     */
 
239
        public static boolean equalPath(IPath path1, IPath path2) {
 
240
                // Check leading separators
 
241
                if (path1.isAbsolute() != path2.isAbsolute() || path1.isUNC() != path2.isUNC()) {
 
242
                        return false;
 
243
                }
 
244
                int i = path1.segmentCount();
 
245
                // Check segment count
 
246
                if (i != path2.segmentCount())
 
247
                        return false;
 
248
                // Check segments in reverse order - later segments more likely to differ
 
249
                boolean caseSensitive = !isWindowsFileSystem();
 
250
                while (--i >= 0) {
 
251
                        if (!(caseSensitive ?
 
252
                                        path1.segment(i).equals(path2.segment(i)) :
 
253
                                        path1.segment(i).equalsIgnoreCase(path2.segment(i)))) {
 
254
                                return false;
 
255
                        }
 
256
                }
 
257
                // Check device last (least likely to differ)
 
258
                if (path1.getDevice() == null) {
 
259
                        return path2.getDevice() == null;
 
260
                } else {
 
261
                        return path1.getDevice().equalsIgnoreCase(path2.getDevice());
 
262
                }
 
263
        }
 
264
 
 
265
    /**
 
266
         * Checks whether path1 is a prefix of path2. To be a prefix, path1's segments
 
267
         * must appear in path1 in the same order, and their device ids must match.
 
268
         * <p>
 
269
         * An empty path is a prefix of all paths with the same device; a root path is a prefix of 
 
270
         * all absolute paths with the same device.
 
271
         * </p>
 
272
         * @return <code>true</code> if path1 is a prefix of path2, and <code>false</code> otherwise
 
273
     * 
 
274
     * Similar to IPath.isPrefixOf(IPath anotherPath), but takes case sensitivity of the file system
 
275
     * into account. 
 
276
     * @since 5.1
 
277
     */
 
278
        public static boolean isPrefix(IPath path1, IPath path2) {
 
279
                if (path1.getDevice() == null) {
 
280
                        if (path2.getDevice() != null) {
 
281
                                return false;
 
282
                        }
 
283
                } else {
 
284
                        if (!path1.getDevice().equalsIgnoreCase(path2.getDevice())) {
 
285
                                return false;
 
286
                        }
 
287
                }
 
288
                if (path1.isEmpty() || (path1.isRoot() && path2.isAbsolute())) {
 
289
                        return true;
 
290
                }
 
291
                int len1 = path1.segmentCount();
 
292
                if (len1 > path2.segmentCount()) {
 
293
                        return false;
 
294
                }
 
295
                boolean caseSensitive = !isWindowsFileSystem();
 
296
                for (int i = 0; i < len1; i++) {
 
297
                        if (!(caseSensitive ?
 
298
                                        path1.segment(i).equals(path2.segment(i)) :
 
299
                                        path1.segment(i).equalsIgnoreCase(path2.segment(i)))) {
 
300
                                return false;
 
301
                        }
 
302
                }
 
303
                return true;
 
304
        }
 
305
 
 
306
        /**
 
307
         * Returns the number of segments which match in path1 and path2
 
308
         * (device ids are ignored), comparing in increasing segment number order.
 
309
         *
 
310
         * @return the number of matching segments
 
311
 
 
312
         * Similar to IPath.matchingFirstSegments(IPath anotherPath), but takes case sensitivity
 
313
         * of the file system into account.
 
314
     * @since 5.1
 
315
         */
 
316
        public static int matchingFirstSegments(IPath path1, IPath path2) {
 
317
                Assert.isNotNull(path1);
 
318
                Assert.isNotNull(path2);
 
319
                int len1 = path1.segmentCount();
 
320
                int len2 = path2.segmentCount();
 
321
                int max = Math.min(len1, len2);
 
322
                int count = 0;
 
323
                boolean caseSensitive = !isWindowsFileSystem();
 
324
                for (int i = 0; i < max; i++) {
 
325
                        if (!(caseSensitive ?
 
326
                                        path1.segment(i).equals(path2.segment(i)) :
 
327
                                        path1.segment(i).equalsIgnoreCase(path2.segment(i)))) {
 
328
                                return count;
 
329
                        }
 
330
                        count++;
 
331
                }
 
332
                return count;
 
333
        }
 
334
 
 
335
        /**
 
336
         * Find location of the program inspecting each path in the path list.
 
337
         * 
 
338
         * @param prog - program to find. For Windows, extensions "com" and "exe"
 
339
         *     can be omitted.
 
340
         * @param pathsStr - the list of paths to inspect separated by path separator
 
341
         *     defined in the platform (i.e. ":" in Unix and ";" in Windows).
 
342
         *     In case pathStr is {@code null} environment variable ${PATH} is inspected.
 
343
         * @return - absolute location of the file on the file system.
 
344
         * @since 5.3
 
345
         */
 
346
        public static IPath findProgramLocation(String prog, String pathsStr) {
 
347
                if (prog==null || prog.trim().length()==0)
 
348
                        return null;
 
349
                
 
350
                if (pathsStr==null)
 
351
                        pathsStr = System.getenv("PATH"); //$NON-NLS-1$
 
352
                
 
353
                if (pathsStr.trim().length()==0)
 
354
                        return null;
 
355
 
 
356
                String locationStr = null;
 
357
                String[] dirs = pathsStr.split(File.pathSeparator);
 
358
 
 
359
                // try to find "prog.exe" or "prog.com" on Windows
 
360
                if (Platform.getOS().equals(Platform.OS_WIN32)) {
 
361
                        for (String dir : dirs) {
 
362
                                IPath dirLocation = new Path(dir);
 
363
                                File file = null;
 
364
 
 
365
                                file = dirLocation.append(prog+".exe").toFile(); //$NON-NLS-1$
 
366
                                if (file.isFile() && file.canRead()) {
 
367
                                        locationStr = file.getAbsolutePath();
 
368
                                        break;
 
369
                                }
 
370
                                file = dirLocation.append(prog+".com").toFile(); //$NON-NLS-1$
 
371
                                if (file.isFile() && file.canRead()) {
 
372
                                        locationStr = file.getAbsolutePath();
 
373
                                        break;
 
374
                                }
 
375
                        }
 
376
                }
 
377
 
 
378
                // check "prog" on Unix and Windows too (if was not found) - could be cygwin or something
 
379
                // do it in separate loop due to performance and correctness of Windows regular case
 
380
                if (locationStr==null) {
 
381
                        for (String dir : dirs) {
 
382
                                IPath dirLocation = new Path(dir);
 
383
                                File file = null;
 
384
                                
 
385
                                file = dirLocation.append(prog).toFile();
 
386
                                if (file.isFile() && file.canRead()) {
 
387
                                        locationStr = file.getAbsolutePath();
 
388
                                        break;
 
389
                                }
 
390
                        }
 
391
                }
 
392
 
 
393
                if (locationStr!=null)
 
394
                        return new Path(locationStr);
 
395
 
 
396
                return null;
 
397
        }
 
398
 
 
399
        /**
 
400
         * Find location of the program inspecting each path in the path list
 
401
         * defined by environment variable ${PATH}.
 
402
         * 
 
403
         * @param prog - program to find. For Windows, extensions "com" and "exe"
 
404
         *     can be omitted.
 
405
         * @return - absolute location of the file on the file system.
 
406
         * @since 5.3
 
407
         */
 
408
        public static IPath findProgramLocation(String prog) {
 
409
                return findProgramLocation(prog, null);
 
410
        }
 
411
}