/******************************************************************************* * Copyright (c) 2002, 2009 IBM Corporation 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: * IBM - Initial API and implementation *******************************************************************************/ package org.eclipse.cdt.debug.mi.core.command.factories.win32; import java.io.ByteArrayOutputStream; import java.util.StringTokenizer; import org.eclipse.cdt.core.CommandLauncher; import org.eclipse.cdt.core.ICommandLauncher; import org.eclipse.cdt.debug.mi.core.command.MIEnvironmentDirectory; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Path; /** * Cygwin implementation of the MIEnvironmentDirectory command. In the cygwin * environment, the paths are DOS paths and need to be converted to cygwin * style paths before passing them to gdb. */ public class CygwinMIEnvironmentDirectory extends MIEnvironmentDirectory { final static private int BUFFER_SIZE = 1000; /** * To prevent to call "cygpath" for each folder (see //bugs.eclipse.org/bugs/show_bug.cgi?id=107202) * we use the "-p" option of "cygpath". * We can not convert the whole path in one shot because the size of the spawner's buffer is limited to 2049, * so we divide the path's folders into groups. */ CygwinMIEnvironmentDirectory(String miVersion, boolean reset, String[] paths) { super(miVersion, reset, paths); String[] newpaths = new String[paths.length]; int index = 0; while(index < paths.length) { int length = 0; StringBuffer sb = new StringBuffer(BUFFER_SIZE); for (int i = index; i < paths.length; i++) { if (length + paths[i].length() < BUFFER_SIZE) { length += paths[i].length(); newpaths[i] = paths[i]; sb.append(paths[i]).append(';'); ++length; } else { convertPath(sb, newpaths, index); index = i; break; } if (i == paths.length - 1) { convertPath(sb, newpaths, index); index = paths.length; break; } } } setParameters(newpaths); } /** * Converts a path to the cygwin path and stores the resulting * folders into the given array starting from <code>index</code>. */ private void convertPath(StringBuffer sb, String[] paths, int index) { if (sb.charAt(sb.length() - 1) == ';') sb.deleteCharAt(sb.length() - 1); String result = convertPath0(sb.toString()); StringTokenizer st = new StringTokenizer(result, ":"); //$NON-NLS-1$ int j = index; while(st.hasMoreTokens()) { if (j >= paths.length) break; paths[j++] = st.nextToken(); } } /** * Converts a windows type path into the cygwin type path using "cygpath" * with the "-p" option. */ private String convertPath0(String path) { String result = path; ICommandLauncher launcher = new CommandLauncher(); ByteArrayOutputStream out = new ByteArrayOutputStream(); try { launcher.execute( new Path("cygpath"), //$NON-NLS-1$ new String[] { "-p", "-u", path }, //$NON-NLS-1$ //$NON-NLS-2$ new String[0], new Path("."), null); //$NON-NLS-1$ } catch (CoreException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (launcher.waitAndRead(out, out) == ICommandLauncher.OK) result = out.toString().trim(); return result; } }