summaryrefslogtreecommitdiffstats
path: root/org.rtems.cdt/src/org/rtems/cdt/Storage.java
diff options
context:
space:
mode:
Diffstat (limited to 'org.rtems.cdt/src/org/rtems/cdt/Storage.java')
-rw-r--r--org.rtems.cdt/src/org/rtems/cdt/Storage.java347
1 files changed, 347 insertions, 0 deletions
diff --git a/org.rtems.cdt/src/org/rtems/cdt/Storage.java b/org.rtems.cdt/src/org/rtems/cdt/Storage.java
new file mode 100644
index 0000000..2e0aee7
--- /dev/null
+++ b/org.rtems.cdt/src/org/rtems/cdt/Storage.java
@@ -0,0 +1,347 @@
+/*
+ * Copyright (c) 2008 Embedded Brains GmbH and others.
+ *
+ * Embedded Brains GmbH
+ * Obere Lagerstr. 30
+ * D-82178 Puchheim
+ * Germany
+ * rtems@embedded-brains.de
+ *
+ * All rights reserved. This program and the accompanying materials are made
+ * available under the terms of the Eclipse Public License Version 1.0 ("EPL")
+ * which accompanies this distribution and is available at
+ *
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * For purposes of the EPL, "Program" will mean the Content.
+ *
+ * Contributors:
+ *
+ * Sebastian Huber (Embedded Brains GmbH) - Initial API and implementation.
+ */
+
+package org.rtems.cdt;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+
+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.IPath;
+import org.eclipse.core.runtime.Path;
+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)) {
+ changePlatform( project, Constants.PLATFORM_DEFAULT);
+ } else {
+ value = getPreference( 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 String prependToPath( String path, String part) {
+ if (path == null || path.isEmpty()) {
+ return part;
+ } else {
+ return part + Constants.PATH_SEPARATOR + path;
+ }
+ }
+
+ public static String prependToPathByPreference( String path, String key) {
+ String basePath = getPreference( key);
+
+ if (basePath != null) {
+ IPath part = new Path( basePath).append( "bin");
+
+ return prependToPath( path, part.toOSString());
+ }
+
+ return path;
+ }
+
+ public static String prependToPathByProperty( IProject project, String path, String key) {
+ String basePath = getProperty( project, key);
+
+ if (basePath != null) {
+ IPath part = new Path( basePath).append( "bin");
+
+ return prependToPath( path, part.toOSString());
+ }
+
+ return path;
+ }
+
+ public static void clearPlatform( IProject project) {
+ setProperty( project, Constants.PLATFORM_KEY, null);
+
+ // Delete discovered paths for all configurations of the project
+ for (IConfiguration cfg : getConfigurations( project)) {
+ CfgDiscoveredPathManager.getInstance().removeDiscoveredInfo(
+ project,
+ new CfgInfoContext( cfg)
+ );
+ }
+ }
+
+ public static String getPlatform( IProject project) {
+ return getPristineProperty( project, Constants.PLATFORM_KEY);
+ }
+
+ public static void changePlatform( IProject project, String newPlatform) {
+ String platform = getPlatform( project);
+
+ // Check if we have already the requested platform
+ if (platform != null && platform == newPlatform) {
+ // Nothing to do
+ return;
+ }
+
+ // Set new platform
+ setProperty( project, Constants.PLATFORM_KEY, newPlatform);
+
+ // Update path prepends
+ String path = null;
+ if (Platform.getOS().equals( Platform.OS_WIN32)) {
+ if (newPlatform.equals( Constants.PLATFORM_CYGWIN)) {
+ path = prependToPathByPreference( path, Constants.CYGWIN_PATH_KEY);
+ } else {
+ path = prependToPathByPreference( path, Constants.MINGW_PATH_KEY);
+ path = prependToPathByPreference( path, Constants.MSYS_PATH_KEY);
+ }
+ }
+ path = prependToPathByProperty( project, path, Constants.BASE_PATH_KEY);
+ setProperty( project, Constants.PATH_PREPEND_KEY, path);
+
+ // Update tools
+ updateTools( project, newPlatform);
+ }
+
+ private static void updateTools( IProject project, String platform) {
+ String bspPath = getProperty( project, Constants.BSP_PATH_KEY);
+ IPath make = new Path( "make");
+
+ // Translate path if necessary
+ if (Platform.getOS().equals( Platform.OS_WIN32)) {
+ if (platform.equals( Constants.PLATFORM_CYGWIN)) {
+ String s [] = bspPath.split( ":");
+ if (s.length > 0) {
+ bspPath = bspPath.replaceFirst( "^" + s [0] + ":", "/cygdrive/" + s [0]);
+ }
+ }
+ bspPath = bspPath.replaceAll( "\\\\", "/");
+ }
+
+ // Create make process builder
+ ProcessBuilder pb = new ProcessBuilder();
+
+ // Change working directory to the Makefile location
+ pb.directory( Activator.getDefault().getMakefileLocation().toFile());
+
+ // Update path environment variable
+ Map<String, String> env = pb.environment();
+ String path = env.get( Constants.PATH_VARIABLE_NAME);
+ String part = getProperty( project, Constants.PATH_PREPEND_KEY);
+ path = Storage.prependToPath( path, part);
+ env.put( Constants.PATH_VARIABLE_NAME, path);
+
+ // On windows we have to search for the make program in the new path environment
+ if (Platform.getOS().equals( Platform.OS_WIN32)) {
+ String parts [] = path.split( Constants.PATH_SEPARATOR);
+ for (String p : parts) {
+ IPath makeCandidate = new Path( p).append( "make.exe");
+ File file = new File( makeCandidate.toOSString());
+ if (file.exists()) {
+ make = makeCandidate;
+ break;
+ }
+ }
+ }
+
+ // Set command line
+ pb.command(
+ make.toOSString(),
+ Constants.BSP_PATH_MAKE_VARIABLE + "=" + bspPath
+ );
+
+ // 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<String> options = new LinkedList<String>();
+ 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;
+ }
+ }
+ }
+ }
+
+ private static void updateTool( IProject project, String toolKey, String command, List<String> options) {
+ List<String> filteredOptions = new LinkedList<String>();
+
+ // 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
+ }
+}