Skip to main content
aboutsummaryrefslogtreecommitdiffstats
blob: 350f72a48f96826686d5471a8fd3513e37253fd8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/*******************************************************************************
 * Copyright (c) 2007, 2011 Wind River Systems, Inc. and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Wind River Systems - initial API and implementation
 *******************************************************************************/
package org.eclipse.tm.internal.tcf.debug.launch;

import java.io.File;
import java.net.InetAddress;
import java.net.URI;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;

import org.eclipse.core.filesystem.URIUtil;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.sourcelookup.AbstractSourceLookupParticipant;
import org.eclipse.debug.core.sourcelookup.ISourceLookupDirector;
import org.eclipse.debug.core.sourcelookup.containers.LocalFileStorage;
import org.eclipse.tm.internal.tcf.debug.launch.TCFLaunchDelegate.PathMapRule;
import org.eclipse.tm.tcf.services.ILineNumbers;

/**
 * The TCF source lookup participant knows how to translate a ILineNumbers.CodeArea
 * into a source file name
 */
public class TCFSourceLookupParticipant extends AbstractSourceLookupParticipant {

    @SuppressWarnings("serial")
    private final LinkedHashMap<String,Object[]> cache = new LinkedHashMap<String,Object[]>(511, 0.75f, true) {
        @Override
        @SuppressWarnings("rawtypes")
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > 1023;
        }
    };

    @Override
    public void sourceContainersChanged(ISourceLookupDirector director) {
        cache.clear();
    }

    public String getSourceName(Object object) throws CoreException {
        if (object instanceof String) {
            return (String)object;
        }
        if (object instanceof ILineNumbers.CodeArea) {
            ILineNumbers.CodeArea area = (ILineNumbers.CodeArea)object;
            return toFileName(area);
        }
        return null;
    }

    public static String toFileName(ILineNumbers.CodeArea area) {
        if (area.directory != null && area.file != null && !isAbsolutePath(area.file)) {
            return area.directory + "/" + area.file;
        }
        return area.file;
    }

    private static boolean isAbsolutePath(String fnm) {
        if (fnm.length() == 0) return false;
        char ch = fnm.charAt(0);
        if (ch == '/' || ch == '\\') return true;
        if (fnm.length() >= 3 && fnm.charAt(1) == ':') {
            ch = fnm.charAt(2);
            if (ch == '/' || ch == '\\') return true;
        }
        return false;
    }

    private String applyPathMap(String fnm) {
        ILaunchConfiguration cfg = getDirector().getLaunchConfiguration();
        if (cfg == null) return fnm;
        try {
            String path_map = cfg.getAttribute(TCFLaunchDelegate.ATTR_PATH_MAP, "");
            if (path_map.length() == 0) return fnm;
            ArrayList<PathMapRule> map = TCFLaunchDelegate.parsePathMapAttribute(path_map);
            for (PathMapRule r : map) {
                String src = r.getSource();
                if (!fnm.startsWith(src)) continue;
                String host = r.getHost();
                if (host != null && host.length() > 0) {
                    if (!InetAddress.getLocalHost().equals(InetAddress.getByName(host))) continue;
                }
                String dst = r.getDestination();
                if (dst == null || dst.length() == 0) continue;
                int l = src.length();
                if (dst.endsWith("/") && l < fnm.length() && fnm.charAt(l) == '/') l++;
                return dst + fnm.substring(l);
            }
            if (fnm.startsWith("/cygdrive/")) {
                fnm = fnm.substring(10, 11) + ":" + fnm.substring(11);
            }
            return fnm;
        }
        catch (Exception x) {
            return fnm;
        }
    }

    private Object[] findSource(String name) throws CoreException {
        Object[] res;
        File file = new File(applyPathMap(name));
        if (file.isAbsolute() && file.exists() && file.isFile()) {
            res = new Object[]{ new LocalFileStorage(file) };
        }
        else {
            res = super.findSourceElements(name);
        }
        ArrayList<Object> list = new ArrayList<Object>();
        for (Object o : res) {
            if (o instanceof IStorage && !(o instanceof IFile)) {
                IPath path = ((IStorage)o).getFullPath();
                if (path != null) {
                    URI uri = URIUtil.toURI(path);
                    IFile[] arr = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(uri);
                    if (arr != null && arr.length > 0) {
                        int cnt = list.size();
                        for (IFile fileResource : arr) {
                            if (fileResource.isAccessible()) {
                                list.add(fileResource);
                            }
                        }
                        if (list.size() > cnt) continue;
                    }
                }
            }
            list.add(o);
        }
        return list.toArray(new Object[list.size()]);
    }

    @Override
    public Object[] findSourceElements(Object object) throws CoreException {
        String name = getSourceName(object);
        if (name == null) return null;
        if (cache.containsKey(name)) return cache.get(name);
        Object[] res = findSource(name);
        cache.put(name, res);
        return res;
    }
}

Back to the top