From: Jan P. <jp...@us...> - 2006-12-12 20:47:49
|
Update of /cvsroot/e-p-i-c/org.epic.debug/src/org/epic/debug/util In directory sc8-pr-cvs5.sourceforge.net:/tmp/cvs-serv4984/src/org/epic/debug/util Added Files: AbstractPathMapper.java RemotePathMapper.java IPathMapper.java NullPathMapper.java CygwinPathMapper.java Removed Files: PathMapping.java PathMapperCygwin.java PathMapper.java Log Message: - Refactored all code which referred to PathMapper. - Fixed bug [ 1614061 ] Unreliable breakpoints in Test::Unit::TestCase. --- NEW FILE: AbstractPathMapper.java --- package org.epic.debug.util; import java.util.ArrayList; import java.util.List; import org.eclipse.core.runtime.IPath; /** * Base class for IPathMapper implementations which translate * paths by mapping from one known path prefix to another. */ public abstract class AbstractPathMapper implements IPathMapper { private final List epicPathPrefixes; private final List dbPathPrefixes; protected AbstractPathMapper() { epicPathPrefixes = new ArrayList(); dbPathPrefixes = new ArrayList(); } protected void addMapping(IPath epicPathPrefix, IPath dbPathPrefix) { epicPathPrefixes.add(epicPathPrefix); dbPathPrefixes.add(dbPathPrefix); } public IPath getDebuggerPath(IPath epicPath) { return swapPrefix(epicPath, epicPathPrefixes, dbPathPrefixes); } public IPath getEpicPath(IPath dbPath) { return swapPrefix(dbPath, dbPathPrefixes, epicPathPrefixes); } public boolean requiresEffectiveIncPath() { return false; } public void setEffectiveIncPath(List inc) { } private IPath swapPrefix(IPath path, List srcPrefixes, List targetPrefixes) { for (int i = 0; i < srcPrefixes.size(); i++) { IPath srcPrefix = (IPath) srcPrefixes.get(i); if (srcPrefix.isPrefixOf(path)) { path = path.removeFirstSegments(srcPrefix.segmentCount()); return ((IPath) targetPrefixes.get(i)).append(path); } } return null; } } --- NEW FILE: RemotePathMapper.java --- package org.epic.debug.util; import java.io.File; import java.util.*; import org.eclipse.core.resources.IFolder; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.*; import org.epic.core.PerlCore; /** * Maps paths of a remote machine to local (EPIC) paths by attempting * look up a file in the local \@INC path. */ public class RemotePathMapper extends AbstractPathMapper { private final String remoteProjectDir; private final List epicInc; private List debuggerInc; public RemotePathMapper(IProject project, String remoteProjectDir) throws CoreException { this.remoteProjectDir = remoteProjectDir; epicInc = convertFilesToPaths( PerlCore.create(project).getEffectiveIncPath()); addMapping(project.getLocation(), new Path(remoteProjectDir)); } public IPath getEpicPath(IPath dbPath) { // Paths under remoteProjectDir are handled by the superclass: IPath ret = super.getEpicPath(dbPath); if (ret != null) return ret; IPath relativePath = makeRelative(dbPath); if (relativePath == null) return null; for (Iterator i = epicInc.iterator(); i.hasNext();) { IPath incDir = (IPath) i.next(); IPath epicPath = incDir.append(relativePath); if (epicPath.toFile().exists()) return epicPath; } return null; } public boolean requiresEffectiveIncPath() { return true; } public void setEffectiveIncPath(List inc) { this.debuggerInc = inc; } private List convertFilesToPaths(List files) { List paths = new ArrayList(files.size()); for (Iterator i = files.iterator(); i.hasNext();) { File file = (File) i.next(); paths.add(Path.fromOSString(file.getAbsolutePath())); } return paths; } private IPath makeRelative(IPath dbPath) { for (Iterator i = debuggerInc.iterator(); i.hasNext();) { IPath incDir = (IPath) i.next(); if (incDir.isPrefixOf(dbPath)) return dbPath.removeFirstSegments(incDir.segmentCount()); } return null; } public void addLinkedFolderMapping(IFolder folder) { addMapping( folder.getLocation(), new Path(remoteProjectDir + "/" + folder.getProjectRelativePath().toString())); } } --- PathMapperCygwin.java DELETED --- --- PathMapping.java DELETED --- --- PathMapper.java DELETED --- --- NEW FILE: CygwinPathMapper.java --- package org.epic.debug.util; import gnu.regexp.*; import java.io.*; import org.eclipse.core.runtime.*; import org.epic.core.util.ProcessExecutor; import org.epic.core.util.ProcessOutput; import org.epic.debug.PerlDebugPlugin; /** * An implementation of IPathMapper which translates Cygwin paths into * Windows paths and vice versa. */ public class CygwinPathMapper extends AbstractPathMapper { public CygwinPathMapper() throws CoreException { try { ProcessExecutor executor = new ProcessExecutor(); ProcessOutput output = executor.execute(new String[] { "mount" }, "", new File(".")); initMappings(output.stdout.replaceAll("\n", "\r\n")); } catch (InterruptedException e) { /* can't occur */ } catch (IOException e) { throw new CoreException(new Status( IStatus.ERROR, PerlDebugPlugin.getUniqueIdentifier(), IStatus.OK, "Could not execute 'mount' to find out path mappings", e)); } } private void initMappings(String mountOutput) throws CoreException { REMatch[] matches = parseMountRegexp().getAllMatches(mountOutput); for (int i = 0; i < matches.length; ++i) { addMapping( new Path(matches[i].toString(1)), new Path(matches[i].toString(2))); } } private RE parseMountRegexp() throws CoreException { try { // e.g. "f:\cygwin\bin on /usr/bin type system (binmode)" return new RE("^(.+)\\s+on\\s+(/.*) type", RE.REG_MULTILINE, RESyntax.RE_SYNTAX_PERL5); } catch (REException e) { throw new CoreException(new Status( IStatus.ERROR, PerlDebugPlugin.getUniqueIdentifier(), IStatus.OK, "Failed to create regexp", e)); } } } --- NEW FILE: NullPathMapper.java --- package org.epic.debug.util; import java.util.List; import org.eclipse.core.runtime.IPath; /** * An implementation of IPathMapper which "translates" paths into * themselves, suitable if both "perl -d" and EPIC access the same * file system. */ public class NullPathMapper implements IPathMapper { public IPath getDebuggerPath(IPath epicPath) { return epicPath; } public IPath getEpicPath(IPath dbPath) { return dbPath; } public boolean requiresEffectiveIncPath() { return false; } public void setEffectiveIncPath(List inc) { } } --- NEW FILE: IPathMapper.java --- package org.epic.debug.util; import java.util.List; import org.eclipse.core.runtime.IPath; /** * Implementors are responsible for translating paths from the file * system known to "perl -d" to the file system known to EPIC * (i.e. the file system which contains the workspace) and vice versa. */ public interface IPathMapper { /** * @param epicPath * an absolute path valid in the EPIC file system * @return the corresponding absolute path valid in the debugger * file system or null if the path could not be translated */ public IPath getDebuggerPath(IPath epicPath); /** * @param dbPath * an absolute path valid in the debugger file system * @return the corresponding absolute path valid in the EPIC file * system or null if the path could not be translated */ public IPath getEpicPath(IPath dbPath); /** * @return true if the implementation wishes to obtain information * about the effective \@INC path from the debugger; * false otherwise */ public boolean requiresEffectiveIncPath(); /** * Provides the debugger's effective \@INC path to the IPathMapper. * This method is only invoked if {@link #requiresEffectiveIncPath()} * returns true. Its invocation is then guaranteed to occur before * any path translations are requested. * * @param inc the effective \@INC path, as a list of IPath objects */ public void setEffectiveIncPath(List inc); } |