/* * Copyright (c) 2008 * Embedded Brains GmbH * Obere Lagerstr. 30 * D-82178 Puchheim * Germany * rtems@embedded-brains.de * * The license and distribution terms for this file may be found in the file * LICENSE in this distribution or at http://www.rtems.com/license/LICENSE. */ package org.rtems.cdt; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.util.LinkedList; import java.util.List; import org.eclipse.cdt.build.core.scannerconfig.CfgInfoContext; import org.eclipse.cdt.build.internal.core.scannerconfig.CfgDiscoveredPathManager; import org.eclipse.cdt.core.model.CoreModel; import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.Platform; import org.eclipse.core.runtime.QualifiedName; public class Storage { private static final String OPTION_SEPARATOR = "\0"; private static final String VALUE_START_TOKEN = "\t"; private static final int EXPECT_OPTION = 0; private static final int EXPECT_COMMAND = 1; private static final int EXPECT_KEY = 2; private static final int TOOL_COMPLETE = 3; public static String getPreference( String key) { return Activator.getDefault().getPreferenceStore().getString( key); } public static String getPristineProperty( IProject project, String key) { String value = null; try { value = project.getPersistentProperty( new QualifiedName( "", key)); } catch (CoreException e) { e.printStackTrace(); } return value; } public static String getProperty( IProject project, String key) { String value = getPristineProperty( project, key); if (value == null) { if (key.startsWith( Constants.TOOL_KEY_PREFIX)) { updateTools( project); } else { value = Activator.getDefault().getPreferenceStore().getString( key); setProperty( project, key, value); } } return value; } public static void setProperty( IProject project, String key, String value) { try { project.setPersistentProperty( new QualifiedName( "", key), value); } catch (CoreException e) { e.printStackTrace(); } } public static IConfiguration [] getConfigurations( IProject project) { ICProjectDescription pd = CoreModel.getDefault().getProjectDescription( project); ICConfigurationDescription cds [] = pd.getConfigurations(); IConfiguration cfgs [] = new IConfiguration [cds.length]; for (int i = 0; i < cds.length; ++i) { cfgs [i] = ManagedBuildManager.getConfigurationForDescription( cds [i]); } return cfgs; } public static IConfiguration getActiveConfiguration( IProject project) { ICProjectDescription pd = CoreModel.getDefault().getProjectDescription( project); ICConfigurationDescription cd = pd.getActiveConfiguration(); IConfiguration cfg = ManagedBuildManager.getConfigurationForDescription( cd); return cfg; } public static void updateTools( IProject project) { String path = getProperty( project, Constants.BSP_PATH_KEY); // Translate path if necessary if (Platform.getOS().equals( Platform.OS_WIN32)) { // FIXME: MinGW? String device = path.split( ":") [0]; path = path.replaceFirst( "^" + device + ":", "/cygdrive/" + device).replaceAll( "\\\\", "/"); } // Create make process builder ProcessBuilder pb = new ProcessBuilder( "make", Constants.BSP_PATH_MAKE_VARIABLE + "=" + path ); // Change working directory to the Makefile location pb.directory( Activator.getDefault().getMakefileLocation().toFile()); // Start make process and parse its output Process p = null; try { p = pb.start(); InputStream is = p.getInputStream(); BufferedReader br = new BufferedReader( new InputStreamReader( is)); String line = br.readLine(); String key = null; String command = null; List options = new LinkedList(); int state = EXPECT_KEY; while (line != null) { switch (state) { case EXPECT_OPTION: if (line.startsWith( VALUE_START_TOKEN)) { options.add( line.substring( 1)); } else { state = TOOL_COMPLETE; continue; } break; case EXPECT_COMMAND: if (line.startsWith( VALUE_START_TOKEN)) { command = line.substring( 1); state = EXPECT_OPTION; } else { throw new IOException( "Unexpected line format"); } break; case EXPECT_KEY: if (line.length() > Constants.TOOL_KEY_PREFIX.length()) { key = line; state = EXPECT_COMMAND; } else { throw new IOException( "Unexpected line format"); } break; case TOOL_COMPLETE: updateTool( project, key, command, options); options.clear(); state = EXPECT_KEY; continue; default: throw new IOException( "Unexpected state"); } line = br.readLine(); } if (state == EXPECT_OPTION) { updateTool( project, key, command, options); } } catch (IOException e) { e.printStackTrace(); } finally { while (true) { try { p.waitFor(); break; } catch (InterruptedException e) { continue; } } } // Delete discovered paths for all configurations of the project for (IConfiguration cfg : getConfigurations( project)) { CfgDiscoveredPathManager.getInstance().removeDiscoveredInfo( project, new CfgInfoContext( cfg) ); } } private static void updateTool( IProject project, String toolKey, String command, List options) { List filteredOptions = new LinkedList(); // Filter options if (toolKey.startsWith( Constants.COMPILER_KEY_PREFIX) || toolKey.startsWith( Constants.LINKER_KEY_PREFIX)) { for (String option : options) { if (!(option.isEmpty() || option.trim().matches( "^-c|-O[0123s]|-g|-W[\\w-]*$"))) { filteredOptions.add( option); } } } else { filteredOptions = options; } // Transform filtered option list into option string value String optionsValue = new String(); if (!options.isEmpty()) { optionsValue = filteredOptions.get( 0); filteredOptions.remove( 0); } for (String option : filteredOptions) { optionsValue += OPTION_SEPARATOR + option; } // Set properties setProperty( project, toolKey, command); setProperty( project, toolKey + Constants.TOOL_OPTIONS_KEY_POSTFIX, optionsValue); } public static String [] getToolOptions( IProject project, String toolKey) { String optionsValue = getProperty( project, toolKey + Constants.TOOL_OPTIONS_KEY_POSTFIX); return optionsValue.split( OPTION_SEPARATOR); } private Storage() { // Do nothing } }