1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-16 04:35:45 +02:00

Bug 484994 - Migrate Mars Arduino support to Neon.

This brings the master branch up to date with everything we've done
in the 8.8 branch. Adjusts for the new ILaunchTarget and targeted
launch delegate.

Also has a start at making more things common in the new build system.
With three extenders of it now in CDT, i.e. Qt, CMake, and Arduino,
it's obvious we can make things more common and make new extenders
less work.

Also undoes some of the work I've done to get Arduino onto the new
build system. Will need to redo it as we do the new common stuff.

Change-Id: I51ce768e0fc60e29c16b05567bd9802d64e33779
This commit is contained in:
Doug Schaefer 2015-12-29 19:09:19 -05:00
parent d8a72d1080
commit 73805d2ea4
68 changed files with 2598 additions and 1256 deletions

View file

@ -0,0 +1,31 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.build.core;
import org.eclipse.launchbar.core.ILaunchDescriptor;
import org.eclipse.launchbar.core.target.ILaunchTarget;
/**
* The manager which managed build configurations.
*
* @noimplement
*/
public interface IBuildConfigurationManager {
/**
* Returns a build configuration that knows how to build the thing described
* by the launch descriptor for the given mode running on the given target.
*
* @param descriptor
* @param mode
* @param target
* @return
*/
CBuildConfiguration getBuildConfiguration(ILaunchDescriptor descriptor, String mode, ILaunchTarget target);
}

View file

@ -0,0 +1,37 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.build.core;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.launchbar.core.ILaunchDescriptor;
import org.eclipse.launchbar.core.target.ILaunchTarget;
/**
* A provider for build configurations.
*/
public interface IBuildConfigurationProvider {
/**
* Returns a build configuration that knows how to build the thing described
* by the launch descriptor for the given mode running on the given target.
*
* @param descriptor
* @param mode
* @param target
* @return
*/
CBuildConfiguration getBuildConfiguration(ILaunchDescriptor descriptor, String mode, ILaunchTarget target);
/**
* Load a previously created build configuration.
*
* @param buildConfig
* @return
*/
CBuildConfiguration loadBuildConfiguration(IBuildConfiguration buildConfig);
}

View file

@ -7,6 +7,7 @@
*******************************************************************************/
package org.eclipse.cdt.build.core.internal;
import org.eclipse.cdt.build.core.IBuildConfigurationManager;
import org.eclipse.cdt.build.core.IToolChainManager;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
@ -21,8 +22,9 @@ public class Activator extends Plugin {
private static Activator plugin;
private static ToolChainManager toolChainManager;
private static CBuildConfigurationCleanup configCleanup;
private static CBuildConfigurationManager buildConfigManager;
@Override
public void start(BundleContext context) throws Exception {
super.start(context);
plugin = this;
@ -30,18 +32,22 @@ public class Activator extends Plugin {
toolChainManager = new ToolChainManager();
context.registerService(IToolChainManager.class, toolChainManager, null);
configCleanup = new CBuildConfigurationCleanup();
ResourcesPlugin.getWorkspace().addResourceChangeListener(configCleanup);
buildConfigManager = new CBuildConfigurationManager();
context.registerService(IBuildConfigurationManager.class, buildConfigManager, null);
ResourcesPlugin.getWorkspace().addResourceChangeListener(buildConfigManager);
// Save participant for toolchain data
ResourcesPlugin.getWorkspace().addSaveParticipant(getId(), new ScannerInfoSaveParticipant());
}
@Override
public void stop(BundleContext context) throws Exception {
plugin = null;
ResourcesPlugin.getWorkspace().removeResourceChangeListener(configCleanup);
configCleanup = null;
toolChainManager = null;
ResourcesPlugin.getWorkspace().removeResourceChangeListener(buildConfigManager);
buildConfigManager = null;
super.stop(context);
}

View file

@ -13,17 +13,54 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.build.core.CBuildConfiguration;
import org.eclipse.cdt.build.core.IBuildConfigurationManager;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.launchbar.core.ILaunchDescriptor;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class CBuildConfigurationCleanup implements IResourceChangeListener {
public class CBuildConfigurationManager
implements IBuildConfigurationManager, IResourceChangeListener, IAdapterFactory {
Map<IBuildConfiguration, CBuildConfiguration> configMap = new HashMap<>();
@Override
public CBuildConfiguration getBuildConfiguration(ILaunchDescriptor descriptor, String mode, ILaunchTarget target) {
// TODO
CBuildConfiguration config = null;
configMap.put(config.getBuildConfiguration(), config);
return config;
}
@SuppressWarnings("unchecked")
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (adaptableObject instanceof IBuildConfiguration) {
if (CBuildConfiguration.class.isAssignableFrom(adapterType)) {
return (T) configMap.get(adaptableObject);
}
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class<?>[] { CBuildConfiguration.class };
}
@Override
public void resourceChanged(IResourceChangeEvent event) {
@ -31,6 +68,15 @@ public class CBuildConfigurationCleanup implements IResourceChangeListener {
if (event.getResource().getType() == IResource.PROJECT) {
IProject project = event.getResource().getProject();
// Clean up the configMap
try {
for (IBuildConfiguration buildConfig : project.getBuildConfigs()) {
configMap.remove(buildConfig);
}
} catch (CoreException e) {
Activator.log(e);
}
// Clean up the config settings
Preferences parentNode = InstanceScope.INSTANCE.getNode(Activator.getId()).node("config"); //$NON-NLS-1$
if (parentNode != null) {

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?pde version="3.8"?><target name="cdt_e4.6" sequenceNumber="2">
<?pde version="3.8"?><target name="cdt_e4.6" sequenceNumber="3">
<locations>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.apache.commons.compress" version="0.0.0"/>
@ -46,6 +46,7 @@
</location>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">
<unit id="org.eclipse.launchbar.feature.group" version="0.0.0"/>
<unit id="org.eclipse.launchbar.remote.feature.group" version="0.0.0"/>
<repository location="https://hudson.eclipse.org/cdt/job/launchbar-master/lastSuccessfulBuild/artifact/repo/target/repository/"/>
</location>
<location includeAllPlatforms="false" includeConfigurePhase="false" includeMode="planner" includeSource="true" type="InstallableUnit">

View file

@ -21,9 +21,11 @@
</license>
<requires>
<import feature="org.eclipse.launchbar" version="1.0.0.qualifier"/>
<import feature="org.eclipse.remote.serial" version="1.0.0.qualifier"/>
<import feature="org.eclipse.remote" version="2.0.0.qualifier"/>
<import feature="org.eclipse.launchbar" version="1.0.0"/>
<import feature="org.eclipse.remote.serial" version="1.0.0"/>
<import feature="org.eclipse.remote" version="2.0.0"/>
<import feature="org.eclipse.remote.console" version="2.0.0"/>
<import feature="org.eclipse.cdt" version="8.8.0"/>
</requires>
<plugin

View file

@ -2,6 +2,7 @@ package org.eclipse.cdt.arduino.core.tests;
import static org.junit.Assert.assertNotEquals;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.junit.Test;
@ -9,7 +10,7 @@ public class BoardManagerTests {
@Test
public void loadPackagesTest() throws Exception {
assertNotEquals(0, ArduinoManager.instance.getPackageIndices().size());
assertNotEquals(0, Activator.getService(ArduinoManager.class).getPackageIndices().size());
}
}

View file

@ -1,8 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry exported="true" kind="lib" path="libs/freemarker-2.3.22.jar"/>
<classpathentry kind="src" path="src/"/>
<classpathentry kind="output" path="target/classes"/>
</classpath>

View file

@ -1,7 +1,7 @@
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.7
org.eclipse.jdt.core.compiler.compliance=1.7
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
org.eclipse.jdt.core.compiler.compliance=1.8
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.7
org.eclipse.jdt.core.compiler.source=1.8

View file

@ -2,7 +2,7 @@ Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: %pluginName
Bundle-SymbolicName: org.eclipse.cdt.arduino.core;singleton:=true
Bundle-Version: 1.0.0.qualifier
Bundle-Version: 2.0.0.qualifier
Bundle-Activator: org.eclipse.cdt.arduino.core.internal.Activator
Bundle-Vendor: %providerName
Require-Bundle: org.eclipse.core.runtime,
@ -15,14 +15,13 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.remote.serial.core;bundle-version="1.0.0",
com.google.gson;bundle-version="2.2.4",
org.apache.commons.compress;bundle-version="1.6.0",
org.eclipse.cdt.build.core;bundle-version="1.0.0",
org.eclipse.cdt.build.gcc.core;bundle-version="1.0.0"
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
org.freemarker;bundle-version="2.3.22"
Bundle-RequiredExecutionEnvironment: JavaSE-1.8
Bundle-ActivationPolicy: lazy
Bundle-ClassPath: libs/freemarker-2.3.22.jar,
.
Bundle-ClassPath: .
Export-Package: org.eclipse.cdt.arduino.core.internal;x-friends:="org.eclipse.cdt.arduino.ui",
org.eclipse.cdt.arduino.core.internal.board;x-friends:="org.eclipse.cdt.arduino.ui",
org.eclipse.cdt.arduino.core.internal.build;x-friends:="org.eclipse.cdt.arduino.ui",
org.eclipse.cdt.arduino.core.internal.console;x-friends:="org.eclipse.cdt.arduino.ui",
org.eclipse.cdt.arduino.core.internal.remote;x-friends:="org.eclipse.cdt.arduino.ui"
Bundle-Localization: plugin

View file

@ -4,5 +4,5 @@ bin.includes = META-INF/,\
plugin.xml,\
templates/,\
about.html,\
plugin.properties,\
libs/
schema/,\
plugin.properties

View file

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<?eclipse version="3.4"?>
<plugin>
<extension-point id="consoleService" name="Arduino Launch Console Service" schema="schema/consoleService.exsd"/>
<extension
point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType
@ -107,19 +108,5 @@
type="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration">
</adapter>
</factory>
<factory
adaptableType="org.eclipse.launchbar.core.target.ILaunchTarget"
class="org.eclipse.cdt.arduino.core.internal.remote.ArduinoTargetAdapterFactory">
<adapter
type="org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection">
</adapter>
</factory>
</extension>
<extension
point="org.eclipse.launchbar.core.launchTargetTypes">
<launchTargetType
id="org.eclipse.cdt.arduino.core.connectionType"
provider="org.eclipse.cdt.arduino.core.internal.remote.ArduinoLaunchTargetProvider">
</launchTargetType>
</extension>
</plugin>

View file

@ -12,6 +12,6 @@
</parent>
<artifactId>org.eclipse.cdt.arduino.core</artifactId>
<version>1.0.0-SNAPSHOT</version>
<version>2.0.0-SNAPSHOT</version>
<packaging>eclipse-plugin</packaging>
</project>

View file

@ -0,0 +1,102 @@
<?xml version='1.0' encoding='UTF-8'?>
<!-- Schema file written by PDE -->
<schema targetNamespace="org.eclipse.cdt.arduino.core" xmlns="http://www.w3.org/2001/XMLSchema">
<annotation>
<appinfo>
<meta.schema plugin="org.eclipse.cdt.arduino.core" id="consoleService" name="Arduino Launch Console Service"/>
</appinfo>
<documentation>
[Enter description of this extension point.]
</documentation>
</annotation>
<element name="extension">
<annotation>
<appinfo>
<meta.element />
</appinfo>
</annotation>
<complexType>
<sequence>
<element ref="provider"/>
</sequence>
<attribute name="point" type="string" use="required">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="id" type="string">
<annotation>
<documentation>
</documentation>
</annotation>
</attribute>
<attribute name="name" type="string">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute translatable="true"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<element name="provider">
<complexType>
<attribute name="class" type="string" use="required">
<annotation>
<documentation>
</documentation>
<appinfo>
<meta.attribute kind="java" basedOn=":org.eclipse.cdt.arduino.core.internal.launch.ArduinoLaunchConsoleService"/>
</appinfo>
</annotation>
</attribute>
</complexType>
</element>
<annotation>
<appinfo>
<meta.section type="since"/>
</appinfo>
<documentation>
[Enter the first release in which this extension point appears.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="examples"/>
</appinfo>
<documentation>
[Enter extension point usage example here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="apiinfo"/>
</appinfo>
<documentation>
[Enter API information here.]
</documentation>
</annotation>
<annotation>
<appinfo>
<meta.section type="implementation"/>
</appinfo>
<documentation>
[Enter information about supplied implementation of this extension point.]
</documentation>
</annotation>
</schema>

View file

@ -10,12 +10,15 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnectionListener;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status;
import org.eclipse.remote.core.IRemoteServicesManager;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
@ -45,13 +48,10 @@ public class Activator extends Plugin {
public void start(BundleContext bundleContext) throws Exception {
plugin = this;
IRemoteServicesManager remoteManager = getService(IRemoteServicesManager.class);
remoteManager.addRemoteConnectionChangeListener(ArduinoRemoteConnectionListener.INSTANCE);
bundleContext.registerService(ArduinoManager.class, new ArduinoManager(), null);
}
public void stop(BundleContext bundleContext) throws Exception {
IRemoteServicesManager remoteManager = getService(IRemoteServicesManager.class);
remoteManager.removeRemoteConnectionChangeListener(ArduinoRemoteConnectionListener.INSTANCE);
plugin = null;
}
@ -61,4 +61,10 @@ public class Activator extends Plugin {
return ref != null ? context.getService(ref) : null;
}
public static ArduinoConsoleService getConsoleService() throws CoreException {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getId(), "consoleService"); //$NON-NLS-1$
IExtension extension = point.getExtensions()[0]; // should only be one
return (ArduinoConsoleService) extension.getConfigurationElements()[0].createExecutableExtension("class"); //$NON-NLS-1$
}
}

View file

@ -21,7 +21,8 @@ public class ArduinoPreferences {
private static final String defaultHome = Paths.get(System.getProperty("user.home"), ".arduinocdt").toString(); //$NON-NLS-1$ //$NON-NLS-2$
private static final String defaultBoardUrls = "http://downloads.arduino.cc/packages/package_index.json" //$NON-NLS-1$
+ "\nhttp://arduino.esp8266.com/stable/package_esp8266com_index.json"; //$NON-NLS-1$
+ "\nhttp://arduino.esp8266.com/stable/package_esp8266com_index.json" //$NON-NLS-1$
+ "\nhttps://adafruit.github.io/arduino-board-index/package_adafruit_index.json"; //$NON-NLS-1$
private static IEclipsePreferences getPrefs() {
return InstanceScope.INSTANCE.getNode(Activator.getId());

View file

@ -20,7 +20,6 @@ import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder;
@ -36,7 +35,15 @@ public class ArduinoProjectGenerator {
this.project = project;
}
public void setupArduinoProject(IProgressMonitor monitor) throws CoreException {
public void generate(IProgressMonitor monitor) throws CoreException {
// Generate files
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
Map<String, Object> fmModel = new HashMap<>();
fmModel.put("projectName", project.getName()); //$NON-NLS-1$
sourceFile = project.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
templateGen.generateFile(fmModel, "arduino.cpp", sourceFile, monitor); //$NON-NLS-1$
// Add natures to project: C, C++, Arduino
IProjectDescription projDesc = project.getDescription();
String[] oldIds = projDesc.getNatureIds();
@ -55,20 +62,8 @@ public class ArduinoProjectGenerator {
project.setDescription(projDesc, monitor);
// Generate files
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
Map<String, Object> fmModel = new HashMap<>();
fmModel.put("projectName", project.getName()); //$NON-NLS-1$
IFolder sourceFolder = project.getFolder("src"); //$NON-NLS-1$
if (!sourceFolder.exists()) {
sourceFolder.create(true, true, monitor);
}
IPathEntry[] entries = new IPathEntry[] { CoreModel.newOutputEntry(sourceFolder.getFullPath()) };
IPathEntry[] entries = new IPathEntry[] { CoreModel.newSourceEntry(project.getFullPath()) };
CoreModel.getDefault().create(project).setRawPathEntries(entries, monitor);
sourceFile = sourceFolder.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
templateGen.generateFile(fmModel, "arduino.cpp", sourceFile, monitor); //$NON-NLS-1$
}
public IFile getSourceFile() {

View file

@ -7,8 +7,6 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal;
import java.io.IOException;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfoChangeListener;
@ -30,7 +28,7 @@ public class ArduinoScannerInfoProvider implements IScannerInfoProvider {
IBuildConfiguration config = project.getActiveBuildConfig();
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
return arduinoConfig.getScannerInfo(resource);
} catch (IOException | CoreException e) {
} catch (CoreException e) {
Activator.log(e);
return null;
}

View file

@ -10,6 +10,8 @@ package org.eclipse.cdt.arduino.core.internal;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringWriter;
import java.net.URISyntaxException;
import java.net.URL;
@ -23,22 +25,19 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import freemarker.cache.TemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ArduinoTemplateGenerator {
public class ArduinoTemplateGenerator implements TemplateLoader {
private final Configuration config;
private Path templateRoot = new Path("/templates"); //$NON-NLS-1$
public ArduinoTemplateGenerator() throws CoreException {
config = new Configuration(Configuration.VERSION_2_3_22);
URL templateDirURL = FileLocator.find(Activator.getContext().getBundle(), new Path("/templates"), null); //$NON-NLS-1$
try {
config.setDirectoryForTemplateLoading(new File(FileLocator.toFileURL(templateDirURL).toURI()));
} catch (IOException | URISyntaxException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Template configuration", e));
}
config.setTemplateLoader(this);
}
public void generateFile(final Object model, String templateFile, final IFile outputFile, IProgressMonitor monitor)
@ -58,8 +57,39 @@ public class ArduinoTemplateGenerator {
}
} catch (IOException | TemplateException e) {
throw new CoreException(
new Status(IStatus.ERROR, Activator.getId(), "Processing template " + templateFile, e));
new Status(IStatus.ERROR, Activator.getId(), "Processing template " + templateFile, e)); //$NON-NLS-1$
}
}
@Override
public Object findTemplateSource(String name) throws IOException {
return FileLocator.find(Activator.getContext().getBundle(), templateRoot.append(name), null);
}
@Override
public long getLastModified(Object source) {
try {
URL url = (URL) source;
if (url.getProtocol().equals("file")) { //$NON-NLS-1$
File file = new File(url.toURI());
return file.lastModified();
} else {
return 0;
}
} catch (URISyntaxException e) {
return 0;
}
}
@Override
public Reader getReader(Object source, String encoding) throws IOException {
URL url = (URL) source;
return new InputStreamReader(url.openStream());
}
@Override
public void closeTemplateSource(Object arg0) throws IOException {
// Nothing to do
}
}

View file

@ -8,11 +8,13 @@
package org.eclipse.cdt.arduino.core.internal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.core.runtime.Platform;
public class HierarchicalProperties {
private String value;
@ -52,7 +54,7 @@ public class HierarchicalProperties {
public void putProperty(String qualifiedKey, String value) {
if (children == null) {
children = new HashMap<>();
children = new LinkedHashMap<>();
}
int i = qualifiedKey.indexOf('.');
@ -61,8 +63,8 @@ public class HierarchicalProperties {
if (child == null) {
child = new HierarchicalProperties();
children.put(qualifiedKey, child);
child.setValue(value);
}
child.setValue(value);
} else {
String key = qualifiedKey.substring(0, i);
HierarchicalProperties child = children.get(key);
@ -76,6 +78,27 @@ public class HierarchicalProperties {
}
public String getValue() {
if (value == null) {
// Try a platform child
String platName = null;
switch (Platform.getOS()) {
case Platform.OS_WIN32:
platName = "windows"; //$NON-NLS-1$
break;
case Platform.OS_MACOSX:
platName = "macosx"; //$NON-NLS-1$
break;
case Platform.OS_LINUX:
platName = "linux"; //$NON-NLS-1$
break;
}
if (platName != null) {
HierarchicalProperties platChild = getChild(platName);
if (platChild != null) {
return platChild.getValue();
}
}
}
return value;
}
@ -93,7 +116,7 @@ public class HierarchicalProperties {
public void putChild(String key, HierarchicalProperties node) {
if (children == null) {
children = new HashMap<>();
children = new LinkedHashMap<>();
}
children.put(key, node);
}

View file

@ -19,6 +19,11 @@ public class Messages extends NLS {
public static String ArduinoLaunchConfigurationDelegate_0;
public static String ArduinoLaunchConfigurationDelegate_1;
public static String ArduinoLaunchConfigurationDelegate_2;
public static String ArduinoManager_0;
public static String ArduinoManager_1;
public static String ArduinoManager_2;
public static String ArduinoPlatform_0;
public static String ArduinoPlatform_1;
public static String ArduinoProjectGenerator_0;
static {

View file

@ -13,6 +13,8 @@ import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
public class ArduinoBoard {
public static final String MENU_QUALIFIER = "menu_"; //$NON-NLS-1$
private String name;
private String id;
@ -50,10 +52,18 @@ public class ArduinoBoard {
return properties.getProperty(key);
}
public HierarchicalProperties getMenus() {
return properties.getChild("menu"); //$NON-NLS-1$
}
public Properties getBoardProperties() {
return properties.flatten();
}
public Properties getMenuProperties(String id, String value) {
return getMenus().getChild(id).getChild(value).flatten();
}
@Override
public int hashCode() {
final int prime = 31;

View file

@ -1,15 +1,18 @@
package org.eclipse.cdt.arduino.core.internal.board;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.core.resources.IProject;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@ -31,6 +34,29 @@ public class ArduinoLibrary {
private int size;
private String checksum;
private Path installPath;
public ArduinoLibrary() {
}
public ArduinoLibrary(Path propertiesFile) throws IOException {
installPath = propertiesFile.getParent();
Properties props = new Properties();
try (FileReader reader = new FileReader(propertiesFile.toFile())) {
props.load(reader);
}
name = props.getProperty("name"); //$NON-NLS-1$
version = props.getProperty("version"); //$NON-NLS-1$
author = props.getProperty("author"); //$NON-NLS-1$
maintainer = props.getProperty("maintainer"); //$NON-NLS-1$
sentence = props.getProperty("sentence"); //$NON-NLS-1$
paragraph = props.getProperty("paragraph"); //$NON-NLS-1$
category = props.getProperty("category"); //$NON-NLS-1$
architectures = Arrays.asList(props.getProperty("architectures").split(",")); //$NON-NLS-1$ //$NON-NLS-2$
}
public String getName() {
return name;
}
@ -144,8 +170,9 @@ public class ArduinoLibrary {
}
public Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("libraries").resolve(name.replace(' ', '_')) //$NON-NLS-1$
.resolve(version);
return installPath != null ? installPath
: ArduinoPreferences.getArduinoHome().resolve("libraries").resolve(name.replace(' ', '_')) //$NON-NLS-1$
.resolve(version);
}
public boolean isInstalled() {
@ -166,39 +193,57 @@ public class ArduinoLibrary {
if (srcPath.toFile().isDirectory()) {
return Collections.singletonList(srcPath);
} else {
// TODO do I need the 'utility' directory?
return Collections.singletonList(installPath);
Path utilityPath = installPath.resolve("utility"); //$NON-NLS-1$
if (utilityPath.toFile().isDirectory()) {
return Arrays.asList(installPath, utilityPath);
} else {
return Collections.singletonList(installPath);
}
}
}
private void getSources(IProject project, Collection<Path> sources, Path dir, boolean recurse) {
private void getSources(Collection<String> sources, Path dir, boolean recurse) {
for (File file : dir.toFile().listFiles()) {
if (file.isDirectory()) {
if (recurse) {
getSources(project, sources, file.toPath(), recurse);
getSources(sources, file.toPath(), recurse);
}
} else {
if (CoreModel.isValidSourceUnitName(project, file.getName())) {
sources.add(file.toPath());
if (ArduinoBuildConfiguration.isSource(file.getName())) {
sources.add(ArduinoBuildConfiguration.pathString(file.toPath()));
}
}
}
}
public Collection<Path> getSources(IProject project) {
List<Path> sources = new ArrayList<>();
public Collection<String> getSources() {
List<String> sources = new ArrayList<>();
Path installPath = getInstallPath();
Path srcPath = installPath.resolve("src"); //$NON-NLS-1$
if (srcPath.toFile().isDirectory()) {
getSources(project, sources, srcPath, true);
getSources(sources, srcPath, true);
} else {
getSources(project, sources, installPath, false);
getSources(sources, installPath, false);
Path utilityPath = installPath.resolve("utility"); //$NON-NLS-1$
if (utilityPath.toFile().isDirectory()) {
getSources(project, sources, utilityPath, false);
getSources(sources, utilityPath, false);
}
}
return sources;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ArduinoLibrary) {
return getName().equals(((ArduinoLibrary) obj).getName());
} else {
return false;
}
}
@Override
public int hashCode() {
return getName().hashCode();
}
}

View file

@ -19,10 +19,14 @@ import java.io.InputStream;
import java.io.Reader;
import java.lang.reflect.Type;
import java.net.URL;
import java.net.URLConnection;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.StandardCopyOption;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.PosixFilePermission;
import java.util.ArrayList;
import java.util.Collection;
@ -59,8 +63,6 @@ import com.google.gson.reflect.TypeToken;
public class ArduinoManager {
public static final ArduinoManager instance = new ArduinoManager();
// Build tool ids
public static final String BOARD_OPTION_ID = "org.eclipse.cdt.arduino.option.board"; //$NON-NLS-1$
public static final String PLATFORM_OPTION_ID = "org.eclipse.cdt.arduino.option.platform"; //$NON-NLS-1$
@ -68,20 +70,23 @@ public class ArduinoManager {
public static final String AVR_TOOLCHAIN_ID = "org.eclipse.cdt.arduino.toolChain.avr"; //$NON-NLS-1$
public static final String LIBRARIES_URL = "http://downloads.arduino.cc/libraries/library_index.json"; //$NON-NLS-1$
private List<PackageIndex> packageIndices;
private LibraryIndex libraryIndex;
public void loadIndices() {
new Job(Messages.ArduinoBoardManager_0) {
protected IStatus run(IProgressMonitor monitor) {
String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$
packageIndices = new ArrayList<>(boardUrls.length);
for (String boardUrl : boardUrls) {
loadPackageIndex(boardUrl, true);
}
synchronized (ArduinoManager.this) {
String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$
packageIndices = new ArrayList<>(boardUrls.length);
for (String boardUrl : boardUrls) {
loadPackageIndex(boardUrl, true);
}
loadLibraryIndex(true);
return Status.OK_STATUS;
loadLibraryIndex(true);
return Status.OK_STATUS;
}
}
}.schedule();
}
@ -93,6 +98,7 @@ public class ArduinoManager {
.resolve(Paths.get(packageUrl.getPath()).getFileName());
File packageFile = packagePath.toFile();
if (download) {
Files.createDirectories(ArduinoPreferences.getArduinoHome());
Files.copy(packageUrl.openStream(), packagePath, StandardCopyOption.REPLACE_EXISTING);
}
if (packageFile.exists()) {
@ -107,7 +113,7 @@ public class ArduinoManager {
}
}
public List<PackageIndex> getPackageIndices() throws CoreException {
public synchronized List<PackageIndex> getPackageIndices() {
if (packageIndices == null) {
String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$
packageIndices = new ArrayList<>(boardUrls.length);
@ -118,18 +124,20 @@ public class ArduinoManager {
return packageIndices;
}
private void loadLibraryIndex(boolean download) {
public void loadLibraryIndex(boolean download) {
try {
URL librariesUrl = new URL(LIBRARIES_URL);
Path librariesPath = ArduinoPreferences.getArduinoHome()
.resolve(Paths.get(librariesUrl.getPath()).getFileName());
File librariesFile = librariesPath.toFile();
if (download) {
Files.createDirectories(ArduinoPreferences.getArduinoHome());
Files.copy(librariesUrl.openStream(), librariesPath, StandardCopyOption.REPLACE_EXISTING);
}
if (librariesFile.exists()) {
try (Reader reader = new FileReader(librariesFile)) {
libraryIndex = new Gson().fromJson(reader, LibraryIndex.class);
libraryIndex.resolve();
}
}
} catch (IOException e) {
@ -146,7 +154,7 @@ public class ArduinoManager {
}
public ArduinoBoard getBoard(String boardName, String platformName, String packageName) throws CoreException {
for (PackageIndex index : packageIndices) {
for (PackageIndex index : getPackageIndices()) {
ArduinoPackage pkg = index.getPackage(packageName);
if (pkg != null) {
ArduinoPlatform platform = pkg.getPlatform(platformName);
@ -161,23 +169,11 @@ public class ArduinoManager {
return null;
}
public List<ArduinoBoard> getBoards() throws CoreException {
List<ArduinoBoard> boards = new ArrayList<>();
for (PackageIndex index : packageIndices) {
for (ArduinoPackage pkg : index.getPackages()) {
for (ArduinoPlatform platform : pkg.getLatestPlatforms()) {
boards.addAll(platform.getBoards());
}
}
}
return boards;
}
public List<ArduinoBoard> getInstalledBoards() throws CoreException {
List<ArduinoBoard> boards = new ArrayList<>();
for (PackageIndex index : packageIndices) {
for (PackageIndex index : getPackageIndices()) {
for (ArduinoPackage pkg : index.getPackages()) {
for (ArduinoPlatform platform : pkg.getInstalledPlatforms()) {
for (ArduinoPlatform platform : pkg.getInstalledPlatforms().values()) {
boards.addAll(platform.getBoards());
}
}
@ -185,8 +181,8 @@ public class ArduinoManager {
return boards;
}
public ArduinoPackage getPackage(String packageName) {
for (PackageIndex index : packageIndices) {
public ArduinoPackage getPackage(String packageName) throws CoreException {
for (PackageIndex index : getPackageIndices()) {
ArduinoPackage pkg = index.getPackage(packageName);
if (pkg != null) {
return pkg;
@ -195,8 +191,8 @@ public class ArduinoManager {
return null;
}
public ArduinoTool getTool(String packageName, String toolName, String version) {
for (PackageIndex index : packageIndices) {
public ArduinoTool getTool(String packageName, String toolName, String version) throws CoreException {
for (PackageIndex index : getPackageIndices()) {
ArduinoPackage pkg = index.getPackage(packageName);
if (pkg != null) {
ArduinoTool tool = pkg.getTool(toolName, version);
@ -208,23 +204,6 @@ public class ArduinoManager {
return null;
}
public ArduinoTool getLatestTool(String packageName, String toolName) {
for (PackageIndex index : packageIndices) {
ArduinoPackage pkg = index.getPackage(packageName);
if (pkg != null) {
ArduinoTool latestTool = null;
for (ArduinoTool tool : pkg.getTools()) {
if (tool.getName().equals(toolName)) {
if (latestTool == null || compareVersions(latestTool.getVersion(), tool.getVersion()) > 1) {
latestTool = tool;
}
}
}
}
}
return null;
}
private static final String LIBRARIES = "libraries"; //$NON-NLS-1$
private IEclipsePreferences getSettings(IProject project) {
@ -237,10 +216,19 @@ public class ArduinoManager {
Type stringSet = new TypeToken<Set<String>>() {
}.getType();
Set<String> libraryNames = new Gson().fromJson(librarySetting, stringSet);
LibraryIndex index = ArduinoManager.instance.getLibraryIndex();
LibraryIndex index = Activator.getService(ArduinoManager.class).getLibraryIndex();
ArduinoPlatform platform = project.getActiveBuildConfig().getAdapter(ArduinoBuildConfiguration.class).getBoard()
.getPlatform();
List<ArduinoLibrary> libraries = new ArrayList<>(libraryNames.size());
for (String name : libraryNames) {
libraries.add(index.getLibrary(name));
ArduinoLibrary lib = index.getLibrary(name);
if (lib == null) {
lib = platform.getLibrary(name);
}
if (lib != null) {
libraries.add(lib);
}
}
return libraries;
}
@ -258,9 +246,9 @@ public class ArduinoManager {
Activator.log(e);
}
new Job("Install libraries") {
new Job(Messages.ArduinoManager_0) {
protected IStatus run(IProgressMonitor monitor) {
MultiStatus mstatus = new MultiStatus(Activator.getId(), 0, "Installing libraries", null);
MultiStatus mstatus = new MultiStatus(Activator.getId(), 0, Messages.ArduinoManager_1, null);
for (ArduinoLibrary library : libraries) {
IStatus status = library.install(monitor);
if (!status.isOK()) {
@ -272,7 +260,7 @@ public class ArduinoManager {
try {
for (IBuildConfiguration config : project.getBuildConfigs()) {
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
arduinoConfig.clearScannerInfo();
arduinoConfig.clearScannerInfoCache();
}
} catch (CoreException e) {
mstatus.add(e.getStatus());
@ -284,115 +272,97 @@ public class ArduinoManager {
public static IStatus downloadAndInstall(String url, String archiveFileName, Path installPath,
IProgressMonitor monitor) {
try {
URL dl = new URL(url);
Path dlDir = ArduinoPreferences.getArduinoHome().resolve("downloads"); //$NON-NLS-1$
Files.createDirectories(dlDir);
Path archivePath = dlDir.resolve(archiveFileName);
Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
boolean isWin = Platform.getOS().equals(Platform.OS_WIN32);
// extract
ArchiveInputStream archiveIn = null;
Exception error = null;
for (int retries = 3; retries > 0 && !monitor.isCanceled(); --retries) {
try {
String compressor = null;
String archiver = null;
if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.BZIP2;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$
compressor = CompressorStreamFactory.GZIP;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.XZ;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$
archiver = ArchiveStreamFactory.ZIP;
}
URL dl = new URL(url);
Path dlDir = ArduinoPreferences.getArduinoHome().resolve("downloads"); //$NON-NLS-1$
Files.createDirectories(dlDir);
Path archivePath = dlDir.resolve(archiveFileName);
URLConnection conn = dl.openConnection();
conn.setConnectTimeout(10000);
conn.setReadTimeout(10000);
Files.copy(conn.getInputStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile()));
if (compressor != null) {
in = new CompressorStreamFactory().createCompressorInputStream(compressor, in);
}
archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in);
boolean isWin = Platform.getOS().equals(Platform.OS_WIN32);
for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn.getNextEntry()) {
if (entry.isDirectory()) {
continue;
// extract
ArchiveInputStream archiveIn = null;
try {
String compressor = null;
String archiver = null;
if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.BZIP2;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$
compressor = CompressorStreamFactory.GZIP;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.XZ;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$
archiver = ArchiveStreamFactory.ZIP;
}
Path entryPath = installPath.resolve(entry.getName());
Files.createDirectories(entryPath.getParent());
InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile()));
if (compressor != null) {
in = new CompressorStreamFactory().createCompressorInputStream(compressor, in);
}
archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in);
if (entry instanceof TarArchiveEntry) {
TarArchiveEntry tarEntry = (TarArchiveEntry) entry;
if (tarEntry.isLink()) {
Path linkPath = installPath.resolve(tarEntry.getLinkName());
Files.createSymbolicLink(entryPath, entryPath.getParent().relativize(linkPath));
for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn
.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}
// Magic file for git tarballs
Path path = Paths.get(entry.getName());
if (path.endsWith("pax_global_header")) { //$NON-NLS-1$
continue;
}
// Strip the first directory of the path
Path entryPath = installPath.resolve(path.subpath(1, path.getNameCount()));
Files.createDirectories(entryPath.getParent());
if (entry instanceof TarArchiveEntry) {
TarArchiveEntry tarEntry = (TarArchiveEntry) entry;
if (tarEntry.isLink()) {
Path linkPath = Paths.get(tarEntry.getLinkName());
linkPath = installPath.resolve(linkPath.subpath(1, linkPath.getNameCount()));
Files.deleteIfExists(entryPath);
Files.createSymbolicLink(entryPath, entryPath.getParent().relativize(linkPath));
} else if (tarEntry.isSymbolicLink()) {
Path linkPath = Paths.get(tarEntry.getLinkName());
Files.deleteIfExists(entryPath);
Files.createSymbolicLink(entryPath, linkPath);
} else {
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
if (!isWin && !tarEntry.isSymbolicLink()) {
int mode = tarEntry.getMode();
Files.setPosixFilePermissions(entryPath, toPerms(mode));
}
} else {
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
if (!isWin) {
int mode = tarEntry.getMode();
Files.setPosixFilePermissions(entryPath, toPerms(mode));
}
} else {
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
} finally {
if (archiveIn != null) {
archiveIn.close();
}
}
} finally {
if (archiveIn != null) {
archiveIn.close();
}
}
// Fix up directory
File[] children = installPath.toFile().listFiles();
if (children.length == 1 && children[0].isDirectory()) {
// make that directory the install path
Path childPath = children[0].toPath();
Path tmpPath = installPath.getParent().resolve("_t"); //$NON-NLS-1$
Files.move(childPath, tmpPath);
Files.delete(installPath);
Files.move(tmpPath, installPath);
return Status.OK_STATUS;
} catch (IOException | CompressorException | ArchiveException e) {
error = e;
// retry
}
return Status.OK_STATUS;
} catch (IOException | CompressorException | ArchiveException e) {
return new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e);
}
}
private static Set<PosixFilePermission> toPerms(int mode) {
Set<PosixFilePermission> perms = new HashSet<>();
if ((mode & 0400) != 0) {
perms.add(PosixFilePermission.OWNER_READ);
}
if ((mode & 0200) != 0) {
perms.add(PosixFilePermission.OWNER_WRITE);
}
if ((mode & 0100) != 0) {
perms.add(PosixFilePermission.OWNER_EXECUTE);
}
if ((mode & 0040) != 0) {
perms.add(PosixFilePermission.GROUP_READ);
}
if ((mode & 0020) != 0) {
perms.add(PosixFilePermission.GROUP_WRITE);
}
if ((mode & 0010) != 0) {
perms.add(PosixFilePermission.GROUP_EXECUTE);
}
if ((mode & 0004) != 0) {
perms.add(PosixFilePermission.OTHERS_READ);
}
if ((mode & 0002) != 0) {
perms.add(PosixFilePermission.OTHERS_WRITE);
}
if ((mode & 0001) != 0) {
perms.add(PosixFilePermission.OTHERS_EXECUTE);
}
return perms;
// out of retries
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoManager_2, error);
}
public static int compareVersions(String version1, String version2) {
@ -440,4 +410,52 @@ public class ArduinoManager {
return 0;
}
private static Set<PosixFilePermission> toPerms(int mode) {
Set<PosixFilePermission> perms = new HashSet<>();
if ((mode & 0400) != 0) {
perms.add(PosixFilePermission.OWNER_READ);
}
if ((mode & 0200) != 0) {
perms.add(PosixFilePermission.OWNER_WRITE);
}
if ((mode & 0100) != 0) {
perms.add(PosixFilePermission.OWNER_EXECUTE);
}
if ((mode & 0040) != 0) {
perms.add(PosixFilePermission.GROUP_READ);
}
if ((mode & 0020) != 0) {
perms.add(PosixFilePermission.GROUP_WRITE);
}
if ((mode & 0010) != 0) {
perms.add(PosixFilePermission.GROUP_EXECUTE);
}
if ((mode & 0004) != 0) {
perms.add(PosixFilePermission.OTHERS_READ);
}
if ((mode & 0002) != 0) {
perms.add(PosixFilePermission.OTHERS_WRITE);
}
if ((mode & 0001) != 0) {
perms.add(PosixFilePermission.OTHERS_EXECUTE);
}
return perms;
}
public static void recursiveDelete(Path directory) throws IOException {
Files.walkFileTree(directory, new SimpleFileVisitor<Path>() {
@Override
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException {
Files.delete(file);
return FileVisitResult.CONTINUE;
}
@Override
public FileVisitResult postVisitDirectory(Path dir, IOException exc) throws IOException {
Files.delete(dir);
return FileVisitResult.CONTINUE;
}
});
}
}

View file

@ -7,12 +7,15 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board;
import java.nio.file.Path;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
public class ArduinoPackage {
private String name;
@ -63,12 +66,16 @@ public class ArduinoPackage {
return Collections.unmodifiableCollection(platforms);
}
public Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("packages").resolve(getName()); //$NON-NLS-1$
}
/**
* Only the latest versions of the platforms.
*
* @return latest platforms
*/
public Collection<ArduinoPlatform> getLatestPlatforms() {
public Map<String, ArduinoPlatform> getAvailablePlatforms() {
Map<String, ArduinoPlatform> platformMap = new HashMap<>();
for (ArduinoPlatform platform : platforms) {
ArduinoPlatform p = platformMap.get(platform.getName());
@ -76,20 +83,17 @@ public class ArduinoPackage {
platformMap.put(platform.getName(), platform);
}
}
return Collections.unmodifiableCollection(platformMap.values());
return platformMap;
}
public Collection<ArduinoPlatform> getInstalledPlatforms() {
public Map<String, ArduinoPlatform> getInstalledPlatforms() {
Map<String, ArduinoPlatform> platformMap = new HashMap<>();
for (ArduinoPlatform platform : platforms) {
if (platform.isInstalled()) {
ArduinoPlatform p = platformMap.get(platform.getName());
if (p == null || ArduinoManager.compareVersions(platform.getVersion(), p.getVersion()) > 0) {
platformMap.put(platform.getName(), platform);
}
platformMap.put(platform.getName(), platform);
}
}
return Collections.unmodifiableCollection(platformMap.values());
return platformMap;
}
public ArduinoPlatform getPlatform(String name) {
@ -122,19 +126,6 @@ public class ArduinoPackage {
return null;
}
public ArduinoTool getLatestTool(String toolName) {
ArduinoTool latestTool = null;
for (ArduinoTool tool : tools) {
if (tool.getName().equals(toolName)) {
if (latestTool == null
|| ArduinoManager.compareVersions(tool.getVersion(), latestTool.getVersion()) > 0) {
latestTool = tool;
}
}
}
return latestTool;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof ArduinoPackage) {

View file

@ -8,8 +8,12 @@
package org.eclipse.cdt.arduino.core.internal.board;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.StringReader;
import java.net.URL;
@ -17,6 +21,8 @@ import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
@ -24,10 +30,12 @@ import java.util.Properties;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.cdt.arduino.core.internal.Messages;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
public class ArduinoPlatform {
@ -44,8 +52,10 @@ public class ArduinoPlatform {
private List<ToolDependency> toolsDependencies;
private ArduinoPackage pkg;
private HierarchicalProperties boardsFile;
private HierarchicalProperties boardsProperties;
private Properties platformProperties;
private Map<String, String> menus = new HashMap<>();
private Map<String, ArduinoLibrary> libraries;
void setOwner(ArduinoPackage pkg) {
this.pkg = pkg;
@ -93,29 +103,43 @@ public class ArduinoPlatform {
return size;
}
public List<ArduinoBoard> getBoards() throws CoreException {
if (isInstalled() && boardsFile == null) {
public List<ArduinoBoard> getBoards() {
if (isInstalled() && boardsProperties == null) {
Properties boardProps = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
try (InputStream is = new FileInputStream(getInstallPath().resolve("boards.txt").toFile()); //$NON-NLS-1$
Reader reader = new InputStreamReader(is, "UTF-8")) { //$NON-NLS-1$
boardProps.load(reader);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading boards.txt", e));
Activator.log(e);
}
boardsFile = new HierarchicalProperties(boardProps);
boardsProperties = new HierarchicalProperties(boardProps);
// Replace the boards with a real ones
boards = new ArrayList<>();
for (Map.Entry<String, HierarchicalProperties> entry : boardsFile.getChildren().entrySet()) {
for (Map.Entry<String, HierarchicalProperties> entry : boardsProperties.getChildren().entrySet()) {
if (entry.getValue().getChild("name") != null) { //$NON-NLS-1$
// assume things with names are boards
boards.add(new ArduinoBoard(entry.getKey(), entry.getValue()).setOwners(this));
}
}
// Build the menu
HierarchicalProperties menuProp = boardsProperties.getChild("menu"); //$NON-NLS-1$
if (menuProp != null) {
for (Map.Entry<String, HierarchicalProperties> entry : menuProp.getChildren().entrySet()) {
menus.put(entry.getKey(), entry.getValue().getValue());
}
}
}
return boards;
}
public HierarchicalProperties getBoardsProperties() {
return boardsProperties;
}
public ArduinoBoard getBoard(String name) throws CoreException {
for (ArduinoBoard board : getBoards()) {
if (name.equals(board.getName())) {
@ -125,6 +149,10 @@ public class ArduinoPlatform {
return null;
}
public String getMenuText(String id) {
return menus.get(id);
}
public List<ToolDependency> getToolsDependencies() {
return toolsDependencies;
}
@ -153,7 +181,7 @@ public class ArduinoPlatform {
platformProperties.load(reader1);
}
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading platform.txt", e));
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading platform.txt", e)); //$NON-NLS-1$
}
}
return platformProperties;
@ -164,8 +192,27 @@ public class ArduinoPlatform {
}
public Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
// TODO remove migration in Neon
Path oldPath = ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()) //$NON-NLS-1$
.resolve(architecture).resolve(version);
Path newPath = getPackage().getInstallPath().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
.resolve(version);
if (Files.exists(oldPath)) {
try {
Files.createDirectories(newPath.getParent());
Files.move(oldPath, newPath);
for (Path parent = oldPath.getParent(); parent != null; parent = parent.getParent()) {
if (Files.newDirectoryStream(parent).iterator().hasNext()) {
break;
} else {
Files.delete(parent);
}
}
} catch (IOException e) {
Activator.log(e);
}
}
return newPath;
}
public List<Path> getIncludePath() {
@ -174,10 +221,98 @@ public class ArduinoPlatform {
installPath.resolve("variants/{build.variant}")); //$NON-NLS-1$
}
private void getSources(Collection<String> sources, Path dir, boolean recurse) {
for (File file : dir.toFile().listFiles()) {
if (file.isDirectory()) {
if (recurse) {
getSources(sources, file.toPath(), recurse);
}
} else {
if (ArduinoBuildConfiguration.isSource(file.getName())) {
sources.add(ArduinoBuildConfiguration.pathString(file.toPath()));
}
}
}
}
public Collection<String> getSources(String core, String variant) {
List<String> sources = new ArrayList<>();
Path srcPath = getInstallPath().resolve("cores").resolve(core); //$NON-NLS-1$
if (srcPath.toFile().isDirectory()) {
getSources(sources, srcPath, true);
}
Path variantPath = getInstallPath().resolve("variants").resolve(variant); //$NON-NLS-1$
if (variantPath.toFile().isDirectory()) {
getSources(sources, variantPath, true);
}
return sources;
}
private void initLibraries() throws CoreException {
libraries = new HashMap<>();
File[] libraryDirs = getInstallPath().resolve("libraries").toFile().listFiles(); //$NON-NLS-1$
if (libraryDirs != null) {
for (File libraryDir : libraryDirs) {
Path propsPath = libraryDir.toPath().resolve("library.properties"); //$NON-NLS-1$
if (propsPath.toFile().exists()) {
try {
ArduinoLibrary lib = new ArduinoLibrary(propsPath);
libraries.put(lib.getName(), lib);
} catch (IOException e) {
throw new CoreException(
new Status(IStatus.ERROR, Activator.getId(), "Loading " + propsPath, e)); //$NON-NLS-1$
}
}
}
}
}
public synchronized Collection<ArduinoLibrary> getLibraries() throws CoreException {
if (libraries == null && isInstalled()) {
initLibraries();
}
return libraries.values();
}
public synchronized ArduinoLibrary getLibrary(String name) throws CoreException {
if (libraries == null && isInstalled()) {
initLibraries();
}
return libraries != null ? libraries.get(name) : null;
}
public IStatus install(IProgressMonitor monitor) {
// Check if we're installed already
if (isInstalled()) {
return Status.OK_STATUS;
try {
ArduinoManager.recursiveDelete(getInstallPath());
} catch (IOException e) {
// just log it, shouldn't break the install
Activator.log(e);
}
}
// Install the tools
for (ToolDependency toolDep : toolsDependencies) {
IStatus status = toolDep.install(monitor);
if (!status.isOK()) {
return status;
}
}
// On Windows install make from bintray
if (Platform.getOS().equals(Platform.OS_WIN32)) {
try {
Path makePath = ArduinoPreferences.getArduinoHome().resolve("make.exe"); //$NON-NLS-1$
if (!makePath.toFile().exists()) {
Files.createDirectories(makePath.getParent());
URL makeUrl = new URL("https://bintray.com/artifact/download/cdtdoug/tools/make.exe"); //$NON-NLS-1$
Files.copy(makeUrl.openStream(), makePath);
makePath.toFile().setExecutable(true, false);
}
} catch (IOException e) {
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoPlatform_0, e);
}
}
// Download platform archive
@ -186,35 +321,17 @@ public class ArduinoPlatform {
return status;
}
// Install the tools
MultiStatus mstatus = null;
for (ToolDependency toolDep : toolsDependencies) {
status = toolDep.install(monitor);
if (!status.isOK()) {
if (mstatus == null) {
mstatus = new MultiStatus(status.getPlugin(), status.getCode(), status.getMessage(),
status.getException());
} else {
mstatus.add(status);
}
}
}
return Status.OK_STATUS;
}
// On Windows install make from equations.org
public IStatus uninstall(IProgressMonitor monitor) {
try {
Path makePath = ArduinoPreferences.getArduinoHome().resolve("tools/make/make.exe");
if (!makePath.toFile().exists()) {
Files.createDirectories(makePath.getParent());
URL makeUrl = new URL("ftp://ftp.equation.com/make/32/make.exe");
Files.copy(makeUrl.openStream(), makePath);
makePath.toFile().setExecutable(true, false);
}
ArduinoManager.recursiveDelete(getInstallPath());
// TODO delete tools that aren't needed any more
return Status.OK_STATUS;
} catch (IOException e) {
mstatus.add(new Status(IStatus.ERROR, Activator.getId(), "downloading make.exe", e));
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoPlatform_1, e);
}
return mstatus != null ? mstatus : Status.OK_STATUS;
}
@Override

View file

@ -7,6 +7,8 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.List;
import java.util.Properties;
@ -50,8 +52,26 @@ public class ArduinoTool {
}
public Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("tools").resolve(pkg.getName()).resolve(name) //$NON-NLS-1$
// TODO remove migration in Neon
Path oldPath = ArduinoPreferences.getArduinoHome().resolve("tools").resolve(pkg.getName()).resolve(name) //$NON-NLS-1$
.resolve(version);
Path newPath = getPackage().getInstallPath().resolve("tools").resolve(name).resolve(version); //$NON-NLS-1$
if (Files.exists(oldPath)) {
try {
Files.createDirectories(newPath.getParent());
Files.move(oldPath, newPath);
for (Path parent = oldPath.getParent(); parent != null; parent = parent.getParent()) {
if (Files.newDirectoryStream(parent).iterator().hasNext()) {
break;
} else {
Files.delete(parent);
}
}
} catch (IOException e) {
Activator.log(e);
}
}
return newPath;
}
public boolean isInstalled() {
@ -70,12 +90,14 @@ public class ArduinoTool {
}
// No valid system
return new Status(IStatus.ERROR, Activator.getId(), "No valid system found for " + name);
return new Status(IStatus.ERROR, Activator.getId(), "No valid system found for " + name); //$NON-NLS-1$
}
public Properties getToolProperties() {
Properties properties = new Properties();
properties.put("runtime.tools." + name + ".path", ArduinoBuildConfiguration.pathString(getInstallPath())); // $NON-NLS-1$ //$NON-NLS-2$
properties.put("runtime.tools." + name + ".path", ArduinoBuildConfiguration.pathString(getInstallPath())); // $NON-NLS-1$ //$NON-NLS-1$//$NON-NLS-2$
properties.put("runtime.tools." + name + '-' + version + ".path", //$NON-NLS-1$//$NON-NLS-2$
ArduinoBuildConfiguration.pathString(getInstallPath())); // $NON-NLS-1$
return properties;
}

View file

@ -60,9 +60,21 @@ public class ArduinoToolSystem {
case Platform.OS_LINUX:
switch (Platform.getOSArch()) {
case Platform.ARCH_X86_64:
return "x86_64-pc-linux-gnu".equals(host); //$NON-NLS-1$
switch (host) {
case "x86_64-pc-linux-gnu": //$NON-NLS-1$
case "x86_64-linux-gnu": //$NON-NLS-1$
return true;
default:
return false;
}
case Platform.ARCH_X86:
return "i686-pc-linux-gnu".equals(host); //$NON-NLS-1$
switch (host) {
case "i686-pc-linux-gnu": //$NON-NLS-1$
case "i686-linux-gnu": //$NON-NLS-1$
return true;
default:
return false;
}
default:
return false;
}

View file

@ -1,5 +1,6 @@
package org.eclipse.cdt.arduino.core.internal.board;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
@ -12,19 +13,20 @@ import java.util.Set;
public class LibraryIndex {
private List<ArduinoLibrary> libraries;
public static final String UNCATEGORIZED = "Uncategorized"; //$NON-NLS-1$
// category name to library name
private Map<String, Set<String>> categories = new HashMap<>();
// library name to latest version of library
private Map<String, ArduinoLibrary> latestLibs = new HashMap<>();
public void resolve() {
public void resolve() throws IOException {
for (ArduinoLibrary library : libraries) {
String name = library.getName();
String category = library.getCategory();
if (category == null) {
category = "Uncategorized"; //$NON-NLS-1$
category = UNCATEGORIZED;
}
Set<String> categoryLibs = categories.get(category);

View file

@ -1,19 +1,12 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.build;
import java.io.BufferedReader;
import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
@ -21,57 +14,71 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.ArduinoTemplateGenerator;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoTool;
import org.eclipse.cdt.arduino.core.internal.board.ToolDependency;
import org.eclipse.cdt.build.core.CBuildConfiguration;
import org.eclipse.cdt.build.core.IToolChain;
import org.eclipse.cdt.build.core.IToolChainManager;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IOutputEntry;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
import org.eclipse.cdt.core.parser.IScannerInfo;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.IResourceProxy;
import org.eclipse.core.resources.IResourceProxyVisitor;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.service.prefs.BackingStoreException;
import org.osgi.service.prefs.Preferences;
public class ArduinoBuildConfiguration extends CBuildConfiguration {
public class ArduinoBuildConfiguration {
private static final String PACKAGE_NAME = "packageName"; //$NON-NLS-1$
private static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$
private static final String BOARD_NAME = "boardName"; //$NON-NLS-1$
private final IBuildConfiguration config;
private static ArduinoManager manager = Activator.getService(ArduinoManager.class);
private ArduinoBoard board;
private Properties properties;
// Cache for scanner info
private IScannerInfo cScannerInfo;
private IScannerInfo cppScannerInfo;
private final static boolean isWindows = Platform.getOS().equals(Platform.OS_WIN32);
private ArduinoBuildConfiguration(IBuildConfiguration config) {
super(config);
this.config = config;
}
private static Map<IBuildConfiguration, ArduinoBuildConfiguration> cache = new HashMap<>();
@ -81,15 +88,13 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
@Override
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (adapterType.equals(ArduinoBuildConfiguration.class) && adaptableObject instanceof IBuildConfiguration) {
synchronized (cache) {
IBuildConfiguration config = (IBuildConfiguration) adaptableObject;
ArduinoBuildConfiguration arduinoConfig = cache.get(config);
if (arduinoConfig == null) {
arduinoConfig = new ArduinoBuildConfiguration(config);
cache.put(config, arduinoConfig);
}
return (T) arduinoConfig;
IBuildConfiguration config = (IBuildConfiguration) adaptableObject;
ArduinoBuildConfiguration arduinoConfig = cache.get(config);
if (arduinoConfig == null) {
arduinoConfig = new ArduinoBuildConfiguration(config);
cache.put(config, arduinoConfig);
}
return (T) arduinoConfig;
}
return null;
}
@ -100,13 +105,17 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
}
}
public static ArduinoBuildConfiguration getConfig(IProject project, ArduinoBoard board, IProgressMonitor monitor)
throws CoreException {
public static ArduinoBuildConfiguration getConfig(IProject project, ArduinoRemoteConnection target,
IProgressMonitor monitor) throws CoreException {
ArduinoBoard board = target.getBoard();
// return it if it exists already
for (IBuildConfiguration config : project.getBuildConfigs()) {
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
if (board.equals(arduinoConfig.getBoard())) {
return arduinoConfig;
if (!config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) {
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
if (arduinoConfig.matches(target)) {
return arduinoConfig;
}
}
}
@ -128,18 +137,39 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
// set it up for the board
IBuildConfiguration config = project.getBuildConfig(newName);
ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
arduinoConfig.setBoard(board);
arduinoConfig.setBoard(target);
return arduinoConfig;
}
public void setActive(IProgressMonitor monitor) throws CoreException {
IProject project = config.getProject();
if (config.equals(project.getActiveBuildConfig())) {
// already set
return;
}
IProjectDescription projectDesc = project.getDescription();
projectDesc.setActiveBuildConfig(config.getName());
project.setDescription(projectDesc, monitor);
// Reindex - assuming for now each config has different compiler
// settings
CCorePlugin.getIndexManager().reindex(CoreModel.getDefault().create(project));
}
public IEclipsePreferences getSettings() {
return (IEclipsePreferences) new ProjectScope(config.getProject()).getNode(Activator.getId()).node("config") //$NON-NLS-1$
.node(config.getName());
}
public void setBoard(ArduinoBoard board) throws CoreException {
this.board = board;
ArduinoPlatform platform = board.getPlatform();
ArduinoPackage pkg = platform.getPackage();
Preferences settings = getSettings();
IEclipsePreferences settings = getSettings();
settings.put(PACKAGE_NAME, pkg.getName());
settings.put(PLATFORM_NAME, platform.getName());
settings.put(BOARD_NAME, board.getName());
@ -150,37 +180,127 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
}
}
public void setBoard(ArduinoRemoteConnection target) throws CoreException {
this.board = target.getBoard();
ArduinoPlatform platform = board.getPlatform();
ArduinoPackage pkg = platform.getPackage();
IEclipsePreferences settings = getSettings();
settings.put(PACKAGE_NAME, pkg.getName());
settings.put(PLATFORM_NAME, platform.getName());
settings.put(BOARD_NAME, board.getName());
HierarchicalProperties menus = board.getMenus();
if (menus != null) {
for (String id : menus.getChildren().keySet()) {
String key = ArduinoBoard.MENU_QUALIFIER + id;
String value = target.getRemoteConnection().getAttribute(key);
if (value != null) {
settings.put(key, value);
}
}
}
try {
settings.flush();
} catch (BackingStoreException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$
}
}
public boolean matches(ArduinoRemoteConnection target) throws CoreException {
ArduinoBoard otherBoard = target.getBoard();
if (!getBoard().equals(otherBoard)) {
return false;
}
IEclipsePreferences settings = getSettings();
HierarchicalProperties menus = board.getMenus();
if (menus != null) {
for (String id : menus.getChildren().keySet()) {
String key = ArduinoBoard.MENU_QUALIFIER + id;
if (!settings.get(key, "").equals(target.getRemoteConnection().getAttribute(key))) { //$NON-NLS-1$
return false;
}
}
}
return true;
}
public ArduinoBoard getBoard() throws CoreException {
if (board == null) {
Preferences settings = getSettings();
IEclipsePreferences settings = getSettings();
String packageName = settings.get(PACKAGE_NAME, ""); //$NON-NLS-1$
String platformName = settings.get(PLATFORM_NAME, ""); //$NON-NLS-1$
String boardName = settings.get(BOARD_NAME, ""); //$NON-NLS-1$
board = ArduinoManager.instance.getBoard(boardName, platformName, packageName);
board = manager.getBoard(boardName, platformName, packageName);
if (board == null) {
// Default to Uno or first one we find
board = manager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
if (board == null) {
List<ArduinoBoard> boards = manager.getInstalledBoards();
if (!boards.isEmpty()) {
board = boards.get(0);
}
}
}
}
return board;
}
private Properties getProperties() throws CoreException {
private synchronized Properties getProperties() throws CoreException {
if (properties == null) {
ArduinoBoard board = getBoard();
ArduinoPlatform platform = board.getPlatform();
properties = board.getBoardProperties();
// IDE generated properties
properties = new Properties();
properties.put("runtime.platform.path", platform.getInstallPath().toString()); //$NON-NLS-1$
properties.put("runtime.ide.version", "10607"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("software", "ARDUINO"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$
String configName = config.getName();
if (configName.equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) {
configName = "default"; //$NON-NLS-1$
}
properties.put("build.path", configName); //$NON-NLS-1$
properties.put("build.variant.path", //$NON-NLS-1$
platform.getInstallPath().resolve("variants").resolve("{build.variant}").toString()); //$NON-NLS-1$ //$NON-NLS-2$
// Platform
properties.putAll(board.getPlatform().getPlatformProperties());
// Tools
for (ToolDependency toolDep : platform.getToolsDependencies()) {
properties.putAll(toolDep.getTool().getToolProperties());
}
properties.put("runtime.ide.version", "10607"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("build.arch", platform.getArchitecture().toUpperCase()); //$NON-NLS-1$
properties.put("build.path", getName()); //$NON-NLS-1$
// Board
ArduinoBoard board = getBoard();
properties.putAll(board.getBoardProperties());
// Menus
IEclipsePreferences settings = getSettings();
HierarchicalProperties menus = board.getMenus();
if (menus != null) {
for (String menuId : menus.getChildren().keySet()) {
String value = settings.get(ArduinoBoard.MENU_QUALIFIER + menuId, ""); //$NON-NLS-1$
if (!value.isEmpty()) {
properties.putAll(board.getMenuProperties(menuId, value));
}
}
}
}
// always do this in case the project changes names
properties.put("build.project_name", getProject().getName()); //$NON-NLS-1$
properties.put("build.project_name", config.getProject().getName()); //$NON-NLS-1$
return properties;
}
public IFolder getBuildFolder() throws CoreException {
IProject project = getProject();
IProject project = config.getProject();
return project.getFolder("build"); //$NON-NLS-1$
}
@ -196,11 +316,12 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
}
public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException {
final IProject project = getProject();
final IProject project = config.getProject();
IFolder buildFolder = getBuildFolder();
if (!buildFolder.exists()) {
buildFolder.create(true, true, monitor);
buildFolder.setDerived(true, monitor);
ICProject cproject = CoreModel.getDefault().create(project);
IOutputEntry output = CoreModel.newOutputEntry(buildFolder.getFullPath());
IPathEntry[] oldEntries = cproject.getRawPathEntries();
@ -227,7 +348,7 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.getType() == IResource.FILE) {
if (CoreModel.isValidSourceUnitName(project, proxy.getName())) {
if (isSource(proxy.getName())) {
Path sourcePath = new File(proxy.requestResource().getLocationURI()).toPath();
sourceFiles.add(pathString(projectPath.relativize(sourcePath)));
}
@ -240,10 +361,8 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
// The list of library sources
List<String> librarySources = new ArrayList<>();
for (ArduinoLibrary lib : ArduinoManager.instance.getLibraries(project)) {
for (Path path : lib.getSources(project)) {
librarySources.add(pathString(path));
}
for (ArduinoLibrary lib : manager.getLibraries(project)) {
librarySources.addAll(lib.getSources());
}
buildModel.put("libraries_srcs", librarySources); //$NON-NLS-1$
buildModel.put("libraries_path", pathString(ArduinoPreferences.getArduinoHome().resolve("libraries"))); //$NON-NLS-1$ //$NON-NLS-2$
@ -263,7 +382,7 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
}
includes += '"' + pathString(include) + '"';
}
for (ArduinoLibrary lib : ArduinoManager.instance.getLibraries(project)) {
for (ArduinoLibrary lib : manager.getLibraries(project)) {
for (Path include : lib.getIncludePath()) {
includes += " -I\"" + pathString(include) + '"'; //$NON-NLS-1$
}
@ -271,33 +390,24 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
properties.put("includes", includes); //$NON-NLS-1$
Path platformPath = platform.getInstallPath();
buildModel.put("platform_path", pathString(platformPath)); //$NON-NLS-1$
Path corePath = platformPath.resolve("cores").resolve((String) properties.get("build.core")); //$NON-NLS-1$ //$NON-NLS-2$
File[] platformFiles = corePath.toFile().listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.endsWith(".cpp") || name.endsWith(".c"); //$NON-NLS-1$ //$NON-NLS-2$
}
});
String[] platformSource = new String[platformFiles.length];
for (int i = 0; i < platformSource.length; ++i) {
platformSource[i] = pathString(platformFiles[i].toPath());
}
buildModel.put("platform_srcs", platformSource); //$NON-NLS-1$
buildModel.put("platform_path", pathString(platformPath).replace("+", "\\+")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
buildModel.put("platform_srcs", //$NON-NLS-1$
platform.getSources(properties.getProperty("build.core"), properties.getProperty("build.variant"))); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("object_file", "$@"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("source_file", "$<"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("archive_file", "core.a"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("archive_file_path", "{build.path}/{archive_file}"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("object_files", "$(PROJECT_OBJS) $(LIBRARIES_OBJS)"); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_cpp_o_pattern", resolveProperty("recipe.cpp.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_c_o_pattern", resolveProperty("recipe.c.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_S_o_pattern", resolveProperty("recipe.S.o.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_ar_pattern", resolveProperty("recipe.ar.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_c_combine_pattern", resolveProperty("recipe.c.combine.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_objcopy_eep_pattern", resolveProperty("recipe.objcopy.eep.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_objcopy_hex_pattern", resolveProperty("recipe.objcopy.hex.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_objcopy_bin_pattern", resolveProperty("recipe.objcopy.bin.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
buildModel.put("recipe_size_pattern", resolveProperty("recipe.size.pattern", properties)); //$NON-NLS-1$ //$NON-NLS-2$
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
@ -305,6 +415,19 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
return makeFile;
}
public static boolean isSource(String filename) {
int i = filename.lastIndexOf('.');
String ext = filename.substring(i + 1);
switch (ext) {
case "cpp": //$NON-NLS-1$
case "c": //$NON-NLS-1$
case "S": //$NON-NLS-1$
return true;
default:
return false;
}
}
private String resolveProperty(String property, Properties dict) {
String res = dict.getProperty(property);
if (res == null) {
@ -332,91 +455,54 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
}
public void setEnvironment(Map<String, String> env) throws CoreException {
// Arduino home to find platforms and libraries
env.put("ARDUINO_HOME", pathString(ArduinoPreferences.getArduinoHome())); //$NON-NLS-1$
// Everything is specified with full path, do not need to add anything
// to the environment.
}
// Add tools to the path
String pathKey = null;
String path = null;
for (Map.Entry<String, String> entry : env.entrySet()) {
if (entry.getKey().equalsIgnoreCase("PATH")) { //$NON-NLS-1$
pathKey = entry.getKey();
path = entry.getValue();
break;
}
}
List<Path> toolPaths = new ArrayList<>();
if (isWindows) {
// Add in the tools/make directory to pick up make
toolPaths.add(ArduinoPreferences.getArduinoHome().resolve("tools/make")); //$NON-NLS-1$
}
ArduinoBoard board = getBoard();
ArduinoPlatform platform = board.getPlatform();
for (ToolDependency dep : platform.getToolsDependencies()) {
ArduinoTool tool = dep.getTool();
Path installPath = tool.getInstallPath();
Path binPath = installPath.resolve("bin"); //$NON-NLS-1$
if (binPath.toFile().exists()) {
toolPaths.add(binPath);
} else {
// use the install dir by default
toolPaths.add(installPath);
}
}
for (Path toolPath : toolPaths) {
if (path != null) {
path = pathString(toolPath) + File.pathSeparatorChar + path;
} else {
path = pathString(toolPath);
}
}
if (pathKey == null) {
pathKey = "PATH"; //$NON-NLS-1$
}
env.put(pathKey, path);
public String getMakeCommand() {
return isWindows ? ArduinoPreferences.getArduinoHome().resolve("make").toString() : "make"; //$NON-NLS-1$ //$NON-NLS-2$
}
public String[] getBuildCommand() throws CoreException {
return new String[] { "make", "-f", getMakeFile().getName() }; //$NON-NLS-1$ //$NON-NLS-2$
return new String[] { getMakeCommand(), "-f", getMakeFile().getName() }; //$NON-NLS-1$
}
public String[] getCleanCommand() throws CoreException {
return new String[] { "make", "-f", getMakeFile().getName(), "clean" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return new String[] { getMakeCommand(), "-f", getMakeFile().getName(), "clean" }; //$NON-NLS-1$ //$NON-NLS-2$
}
public String[] getSizeCommand() throws CoreException {
// TODO this shouldn't be in the makefile
// should be like the upload command
return new String[] { "make", "-f", getMakeFile().getName(), "size" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
return new String[] { getMakeCommand(), "-f", getMakeFile().getName(), "size" }; //$NON-NLS-1$ //$NON-NLS-2$
}
public String getCodeSizeRegex() throws CoreException {
return (String) getBoard().getPlatform().getPlatformProperties().getProperty("recipe.size.regex"); //$NON-NLS-1$
return getBoard().getPlatform().getPlatformProperties().getProperty("recipe.size.regex"); //$NON-NLS-1$
}
public int getMaxCodeSize() throws CoreException {
String sizeStr = (String) getBoard().getBoardProperties().getProperty("upload.maximum_size"); //$NON-NLS-1$
String sizeStr = getProperties().getProperty("upload.maximum_size"); //$NON-NLS-1$
return sizeStr != null ? Integer.parseInt(sizeStr) : -1;
}
public String getDataSizeRegex() throws CoreException {
return (String) getBoard().getPlatform().getPlatformProperties().getProperty("recipe.size.regex.data"); //$NON-NLS-1$
return getBoard().getPlatform().getPlatformProperties().getProperty("recipe.size.regex.data"); //$NON-NLS-1$
}
public int getMaxDataSize() throws CoreException {
String sizeStr = (String) getBoard().getBoardProperties().getProperty("upload.maximum_data_size"); //$NON-NLS-1$
String sizeStr = getProperties().getProperty("upload.maximum_data_size"); //$NON-NLS-1$
return sizeStr != null ? Integer.parseInt(sizeStr) : -1;
}
public String[] getUploadCommand(String serialPort) throws CoreException {
String toolName = getProperties().getProperty("upload.tool"); //$NON-NLS-1$
ArduinoTool tool = board.getPlatform().getTool(toolName);
Properties properties = getProperties();
properties.put("runtime.tools." + toolName + ".path", pathString(tool.getInstallPath())); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("serial.port", serialPort); //$NON-NLS-1$
if (serialPort.startsWith("/dev/")) {
// Little bit of weirdness needed for the bossac tool
if (serialPort.startsWith("/dev/")) { //$NON-NLS-1$
properties.put("serial.port.file", serialPort.substring(5)); //$NON-NLS-1$
} else {
properties.put("serial.port.file", serialPort); //$NON-NLS-1$
@ -426,86 +512,58 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
properties.put("cmd.path", "{tools." + toolName + ".cmd.path}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
properties.put("config.path", "{tools." + toolName + ".config.path}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
properties.put("upload.verbose", "{tools." + toolName + ".upload.params.quiet}"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// properties for the tool flattened
HierarchicalProperties toolsProps = new HierarchicalProperties(getBoard().getPlatform().getPlatformProperties())
.getChild("tools"); //$NON-NLS-1$
if (toolsProps != null) {
HierarchicalProperties toolProps = toolsProps.getChild(toolName);
if (toolProps != null) {
properties.putAll(toolProps.flatten());
}
}
String command = resolveProperty("tools." + toolName + ".upload.pattern", properties); //$NON-NLS-1$ //$NON-NLS-2$
// TODO make this a preference
properties.put("upload.verbose", properties.getProperty("upload.params.verbose", "")); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
// TODO needed this for esptool
properties.put("upload.resetmethod", "ck"); //$NON-NLS-1$ //$NON-NLS-2$
String command = resolveProperty("upload.pattern", properties); //$NON-NLS-1$
if (command == null) {
return new String[] { "command not specified" }; //$NON-NLS-1$
}
if (isWindows) {
return command.split(" "); //$NON-NLS-1$
return splitCommand(command);
} else {
return new String[] { "sh", "-c", command }; //$NON-NLS-1$ //$NON-NLS-2$
}
}
public IToolChain getToolChainx() {
try {
IToolChain toolChain = super.getToolChain();
if (toolChain == null) {
// figure out which one it is
IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class);
ArduinoPlatform platform = board.getPlatform();
String compilerPath = resolveProperty("compiler.path", platform.getPlatformProperties()); //$NON-NLS-1$
if (compilerPath != null) {
// TODO what if it is null?
Path path = Paths.get(compilerPath);
for (ToolDependency toolDep : platform.getToolsDependencies()) {
ArduinoTool tool = toolDep.getTool();
if (path.startsWith(tool.getInstallPath())) {
}
}
}
}
return toolChain;
} catch (CoreException e) {
Activator.log(e);
return null;
}
}
@Override
public IScannerInfo getScannerInfo(IResource resource) throws IOException {
IScannerInfo info = super.getScannerInfo(resource);
if (info == null) {
// what language is this resource and pick the right recipe
String recipe;
switch (CCorePlugin.getContentType(resource.getProject(), resource.getName()).getId()) {
public IScannerInfo getScannerInfo(IResource resource) throws CoreException {
IContentType contentType = CCorePlugin.getContentType(resource.getProject(), resource.getName());
if (contentType != null) {
// what language is this resource and pick the right path;
switch (contentType.getId()) {
case CCorePlugin.CONTENT_TYPE_CXXSOURCE:
case CCorePlugin.CONTENT_TYPE_CXXHEADER:
recipe = "recipe.cpp.o.pattern"; //$NON-NLS-1$
break;
if (cppScannerInfo == null) {
cppScannerInfo = calculateScannerInfo("recipe.cpp.o.pattern", resource); //$NON-NLS-1$
}
return cppScannerInfo;
default:
recipe = "recipe.c.o.pattern"; //$NON-NLS-1$
}
try {
ArduinoPlatform platform = getBoard().getPlatform();
Properties properties = new Properties();
properties.putAll(getProperties());
Path resourcePath = new File(resource.getLocationURI()).toPath();
Path sourcePath = getBuildDirectory().toPath().relativize(resourcePath);
properties.put("source_file", pathString(sourcePath)); //$NON-NLS-1$
properties.put("object_file", "-"); //$NON-NLS-1$ //$NON-NLS-2$
String includes = ""; //$NON-NLS-1$
for (Path include : platform.getIncludePath()) {
includes += " -I\"" + pathString(include) + '"'; //$NON-NLS-1$
if (cScannerInfo == null) {
cScannerInfo = calculateScannerInfo("recipe.c.o.pattern", resource); //$NON-NLS-1$
}
Collection<ArduinoLibrary> libs = ArduinoManager.instance.getLibraries(getProject());
for (ArduinoLibrary lib : libs) {
for (Path path : lib.getIncludePath()) {
includes += " -I\"" + pathString(path) + '"'; //$NON-NLS-1$
}
}
properties.put("includes", includes); //$NON-NLS-1$
List<String> cmd = Arrays.asList(resolveProperty(recipe, properties).split(" ")); //$NON-NLS-1$
// TODO for reals
info = getToolChain().getScannerInfo(cmd.get(0), cmd.subList(1, cmd.size()), null, resource, null);
} catch (CoreException e) {
throw new IOException(e);
return cScannerInfo;
}
}
return info;
// use the cpp scanner info if all else fails
return cppScannerInfo;
}
public void clearScannerInfoCache() {
cppScannerInfo = null;
cScannerInfo = null;
}
public static String pathString(Path path) {
@ -516,4 +574,109 @@ public class ArduinoBuildConfiguration extends CBuildConfiguration {
return str;
}
private IScannerInfo calculateScannerInfo(String recipe, IResource resource) throws CoreException {
try {
ArduinoPlatform platform = getBoard().getPlatform();
Properties properties = new Properties();
properties.putAll(getProperties());
Path tmpFile = Files.createTempFile("cdt", ".cpp"); //$NON-NLS-1$ //$NON-NLS-2$
properties.put("source_file", pathString(tmpFile)); //$NON-NLS-1$
properties.put("object_file", "-"); //$NON-NLS-1$ //$NON-NLS-2$
String includes = "-E -P -v -dD"; //$NON-NLS-1$
for (Path include : platform.getIncludePath()) {
includes += " -I\"" + pathString(include) + '"'; //$NON-NLS-1$
}
Collection<ArduinoLibrary> libs = manager.getLibraries(config.getProject());
for (ArduinoLibrary lib : libs) {
for (Path path : lib.getIncludePath()) {
includes += " -I\"" + pathString(path) + '"'; //$NON-NLS-1$
}
}
properties.put("includes", includes); //$NON-NLS-1$
String[] command;
if (isWindows) {
command = splitCommand(resolveProperty(recipe, properties));
} else {
command = new String[] { "sh", "-c", resolveProperty(recipe, properties) }; //$NON-NLS-1$ //$NON-NLS-2$
}
ProcessBuilder processBuilder = new ProcessBuilder(command).directory(tmpFile.getParent().toFile())
.redirectErrorStream(true);
setEnvironment(processBuilder.environment());
Process process = processBuilder.start();
Map<String, String> symbols = new HashMap<>();
List<String> includePath = new ArrayList<>();
Pattern definePattern = Pattern.compile("#define (.*)\\s(.*)"); //$NON-NLS-1$
boolean inIncludePaths = false;
try (BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
for (String line = reader.readLine(); line != null; line = reader.readLine()) {
if (inIncludePaths) {
if (line.equals("End of search list.")) { //$NON-NLS-1$
inIncludePaths = false;
} else {
includePath.add(line.trim());
}
} else if (line.startsWith("#define ")) { //$NON-NLS-1$
Matcher matcher = definePattern.matcher(line);
if (matcher.matches()) {
symbols.put(matcher.group(1), matcher.group(2));
}
} else if (line.equals("#include <...> search starts here:")) { //$NON-NLS-1$
inIncludePaths = true;
}
}
}
Files.delete(tmpFile);
ExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(symbols,
includePath.toArray(new String[includePath.size()]));
return scannerInfo;
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Compiler built-ins", e)); //$NON-NLS-1$
}
}
private String[] splitCommand(String command) {
// TODO deal with quotes properly, for now just strip
return command.replaceAll("\"", "").split("\\s+"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
}
public ArduinoConsoleParser[] getBuildConsoleParsers() {
// ../src/Test.cpp:4:1: error: 'x' was not declared in this scope
return new ArduinoConsoleParser[] { new ArduinoErrorParser("(.*?):(\\d+):(\\d+:)? (fatal )?error: (.*)") { //$NON-NLS-1$
@Override
protected int getSeverity(Matcher matcher) {
return IMarker.SEVERITY_ERROR;
}
@Override
protected String getMessage(Matcher matcher) {
return matcher.group(matcher.groupCount());
}
@Override
protected int getLineNumber(Matcher matcher) {
return Integer.parseInt(matcher.group(2));
}
@Override
protected String getFileName(Matcher matcher) {
return matcher.group(1);
}
@Override
protected int getLinkOffset(Matcher matcher) {
return 0;
}
@Override
protected int getLinkLength(Matcher matcher) {
return matcher.group(1).length() + 1 + matcher.group(2).length() + 1 + matcher.group(3).length();
}
} };
}
}

View file

@ -15,8 +15,7 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.build.core.CConsoleParser;
import org.eclipse.cdt.build.core.IConsoleService;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
@ -27,8 +26,7 @@ import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/**
* This class is responsible for generating the Makefile for the current build
* config.
* This class is responsible for generating the Makefile for the current build config.
*/
public class ArduinoBuilder extends IncrementalProjectBuilder {
@ -40,8 +38,8 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
try {
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
IConsoleService consoleService = Activator.getService(IConsoleService.class);
consoleService.writeOutput(String.format("Building %s\n", project.getName()));
ArduinoConsoleService consoleService = Activator.getConsoleService();
consoleService.writeOutput(String.format("\nBuilding %s\n", project.getName()));
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
config.generateMakeFile(monitor);
@ -51,17 +49,15 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
config.setEnvironment(processBuilder.environment());
Process process = processBuilder.start();
consoleService.monitor(process, config.getConsoleParsers().toArray(new CConsoleParser[0]),
config.getBuildDirectory().toPath());
consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder());
if (process.exitValue() == 0) {
showSizes(config, consoleService);
}
config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor);
consoleService.writeOutput("\n"); //$NON-NLS-1$
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
}
// TODO if there are references we want to watch, return them here
@ -74,8 +70,8 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
IProject project = getProject();
project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE);
IConsoleService consoleService = Activator.getService(IConsoleService.class);
consoleService.writeOutput(String.format("Cleaning %s\n", project.getName()));
ArduinoConsoleService consoleService = Activator.getConsoleService();
consoleService.writeOutput(String.format("\nCleaning %s\n", project.getName()));
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
@ -84,17 +80,15 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
config.setEnvironment(processBuilder.environment());
Process process = processBuilder.start();
consoleService.monitor(process, config.getConsoleParsers().toArray(new CConsoleParser[0]),
config.getBuildDirectory().toPath());
consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder());
config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor);
consoleService.writeOutput("\n"); //$NON-NLS-1$
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); //$NON-NLS-1$
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
}
}
private void showSizes(ArduinoBuildConfiguration config, IConsoleService console) throws CoreException {
private void showSizes(ArduinoBuildConfiguration config, ArduinoConsoleService console) throws CoreException {
try {
int codeSize = -1;
int dataSize = -1;
@ -102,7 +96,7 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
String codeSizeRegex = config.getCodeSizeRegex();
Pattern codeSizePattern = codeSizeRegex != null ? Pattern.compile(codeSizeRegex) : null;
String dataSizeRegex = config.getDataSizeRegex();
Pattern dataSizePattern = codeSizeRegex != null ? Pattern.compile(dataSizeRegex) : null;
Pattern dataSizePattern = dataSizeRegex != null ? Pattern.compile(dataSizeRegex) : null;
if (codeSizePattern == null && dataSizePattern == null) {
return;
@ -138,11 +132,13 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
}
console.writeOutput(" bytes\n");
console.writeOutput("Initial RAM usage: " + dataSize);
if (maxCodeSize > 0) {
console.writeOutput(" of maximum " + maxDataSize);
if (maxDataSize >= 0) {
console.writeOutput("Initial RAM usage: " + dataSize);
if (maxCodeSize > 0) {
console.writeOutput(" of maximum " + maxDataSize);
}
console.writeOutput(" bytes\n");
}
console.writeOutput(" bytes\n");
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Checking sizes", e));
}

View file

@ -0,0 +1,60 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.console;
public abstract class ArduinoConsoleParser {
private final String pattern;
private final int flags;
private final String lineQualifier;
protected ArduinoConsoleParser(String pattern, int flags, String lineQualifier) {
this.pattern = pattern;
this.flags = flags;
this.lineQualifier = lineQualifier;
}
/**
* Returns the pattern to be used for matching. The pattern is a string
* representing a regular expression.
*
* @return the regular expression to be used for matching
*/
public String getPattern() {
return pattern;
}
/**
* Returns the flags to use when compiling this pattern match listener's
* regular expression, as defined by by
* <code>Pattern.compile(String regex, int flags)</code>
*
* @return the flags to use when compiling this pattern match listener's
* regular expression
* @see java.util.regex.Pattern#compile(java.lang.String, int)
*/
public int getCompilerFlags() {
return flags;
}
/**
* Returns a simple regular expression used to identify lines that may match
* this pattern matcher's complete pattern, or <code>null</code>. Use of
* this attribute can improve performance by disqualifying lines from the
* search. When a line is found containing a match for this expression, the
* line is searched from the beginning for this pattern matcher's complete
* pattern. Lines not containing this pattern are discarded.
*
* @return a simple regular expression used to identify lines that may match
* this pattern matcher's complete pattern, or <code>null</code>
*/
public String getLineQualifier() {
return lineQualifier;
}
}

View file

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.console;
import java.io.IOException;
import org.eclipse.core.resources.IFolder;
public interface ArduinoConsoleService {
void monitor(Process process, ArduinoConsoleParser[] consoleParsers, IFolder buildDirectory) throws IOException;
void writeOutput(String msg) throws IOException;
void writeError(String msg) throws IOException;
}

View file

@ -0,0 +1,83 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.console;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.core.model.ICModelMarker;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.CoreException;
public abstract class ArduinoErrorParser extends ArduinoConsoleParser {
public static final String LINK_OFFSET = "arduino.link.offset"; //$NON-NLS-1$
public static final String LINK_LENGTH = "arduino.link.length"; //$NON-NLS-1$
private final Pattern errorPattern;
public ArduinoErrorParser(String pattern, int flags, String lineQualifier) {
super(pattern, flags, lineQualifier);
this.errorPattern = Pattern.compile(pattern);
}
public ArduinoErrorParser(String pattern) {
this(pattern, 0, null);
}
protected abstract String getFileName(Matcher matcher);
protected abstract int getLineNumber(Matcher matcher);
protected abstract String getMessage(Matcher matcher);
protected abstract int getSeverity(Matcher matcher);
protected abstract int getLinkOffset(Matcher matcher);
protected abstract int getLinkLength(Matcher matcher);
public IMarker generateMarker(IFolder buildDirectory, String text) throws CoreException {
Matcher matcher = errorPattern.matcher(text);
if (matcher.matches()) {
String fileName = getFileName(matcher);
IFile file = buildDirectory.getFile(fileName);
if (file.exists()) {
for (IMarker marker : file.findMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, false,
IResource.DEPTH_ZERO)) {
if (marker.getAttribute(IMarker.SEVERITY, -1) == getSeverity(matcher)
&& marker.getAttribute(IMarker.LINE_NUMBER, -1) == getLineNumber(matcher)
&& marker.getAttribute(IMarker.MESSAGE, "").equals(getMessage(matcher))) { //$NON-NLS-1$
return marker;
}
}
try {
IMarker marker = file.createMarker(ICModelMarker.C_MODEL_PROBLEM_MARKER);
marker.setAttribute(IMarker.MESSAGE, getMessage(matcher));
marker.setAttribute(IMarker.SEVERITY, getSeverity(matcher));
marker.setAttribute(IMarker.LINE_NUMBER, getLineNumber(matcher));
marker.setAttribute(IMarker.CHAR_START, -1);
marker.setAttribute(IMarker.CHAR_END, -1);
marker.setAttribute(LINK_OFFSET, getLinkOffset(matcher));
marker.setAttribute(LINK_LENGTH, getLinkLength(matcher));
return marker;
} catch (CoreException e) {
Activator.log(e);
return null;
}
}
}
return null;
}
}

View file

@ -0,0 +1,49 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.launch;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.debug.core.DebugEvent;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.ISourceLocator;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.launch.TargetedLaunch;
import org.eclipse.remote.core.IRemoteConnection;
public class ArduinoLaunch extends TargetedLaunch {
private final ArduinoRemoteConnection remote;
private boolean wasOpen;
public ArduinoLaunch(ILaunchConfiguration launchConfiguration, String mode, ISourceLocator locator,
ILaunchTarget target) {
super(launchConfiguration, mode, target, locator);
IRemoteConnection connection = target.getAdapter(IRemoteConnection.class);
this.remote = connection.getService(ArduinoRemoteConnection.class);
DebugPlugin.getDefault().addDebugEventListener(this);
}
public void start() {
this.wasOpen = remote.getRemoteConnection().isOpen();
if (wasOpen) {
remote.pause();
}
}
@Override
public void handleDebugEvents(DebugEvent[] events) {
super.handleDebugEvents(events);
if (isTerminated() && wasOpen) {
remote.resume();
wasOpen = false;
}
}
}

View file

@ -14,53 +14,48 @@ import java.io.IOException;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.Messages;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.build.core.IConsoleService;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunch;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.model.LaunchConfigurationDelegate;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.launch.ITargetedLaunch;
import org.eclipse.launchbar.core.target.launch.LaunchConfigurationTargetedDelegate;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDelegate {
public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTargetedDelegate {
public static final String TYPE_ID = "org.eclipse.cdt.arduino.core.launchConfigurationType"; //$NON-NLS-1$
public static final String CONNECTION_NAME = Activator.getId() + ".connectionName"; //$NON-NLS-1$
private static IRemoteConnection getTarget(ILaunchConfiguration configuration) throws CoreException {
IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType connectionType = remoteManager.getConnectionType(ArduinoRemoteConnection.TYPE_ID);
String connectionName = configuration.getAttribute(CONNECTION_NAME, ""); //$NON-NLS-1$
return connectionType.getConnection(connectionName);
@Override
public ITargetedLaunch getLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target)
throws CoreException {
return new ArduinoLaunch(configuration, mode, null, target);
}
@Override
public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, IProgressMonitor monitor)
throws CoreException {
IRemoteConnection target = getTarget(configuration);
public boolean buildForLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target,
IProgressMonitor monitor) throws CoreException {
IRemoteConnection connection = target.getAdapter(IRemoteConnection.class);
if (target != null) {
ArduinoRemoteConnection arduinoTarget = target.getService(ArduinoRemoteConnection.class);
ArduinoBoard targetBoard = arduinoTarget.getBoard();
ArduinoRemoteConnection arduinoTarget = connection.getService(ArduinoRemoteConnection.class);
// 1. make sure proper build config is set active
IProject project = configuration.getMappedResources()[0].getProject();
ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, targetBoard,
ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, arduinoTarget,
monitor);
arduinoConfig.setActive(monitor);
}
// 2. Run the build
return super.buildForLaunch(configuration, mode, monitor);
return super.buildForLaunch(configuration, mode, target, monitor);
}
@Override
@ -73,61 +68,40 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
@Override
public void launch(final ILaunchConfiguration configuration, String mode, final ILaunch launch,
IProgressMonitor monitor) throws CoreException {
new Job(Messages.ArduinoLaunchConfigurationDelegate_0) {
protected IStatus run(IProgressMonitor monitor) {
try {
IConsoleService consoleService = Activator.getService(IConsoleService.class);
IRemoteConnection target = getTarget(configuration);
if (target == null) {
return new Status(IStatus.ERROR, Activator.getId(),
Messages.ArduinoLaunchConfigurationDelegate_2);
}
ArduinoRemoteConnection arduinoTarget = target.getService(ArduinoRemoteConnection.class);
try {
ILaunchTarget target = ((ITargetedLaunch) launch).getLaunchTarget();
IRemoteConnection connection = target.getAdapter(IRemoteConnection.class);
if (connection == null) {
throw new CoreException(
new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoLaunchConfigurationDelegate_2));
}
ArduinoRemoteConnection arduinoTarget = connection.getService(ArduinoRemoteConnection.class);
// The project
IProject project = (IProject) configuration.getMappedResources()[0];
// The project
IProject project = (IProject) configuration.getMappedResources()[0];
// The build config
ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project,
arduinoTarget.getBoard(), monitor);
String[] uploadCmd = arduinoConfig.getUploadCommand(arduinoTarget.getPortName());
// The build config
ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, arduinoTarget,
monitor);
String[] uploadCmd = arduinoConfig.getUploadCommand(arduinoTarget.getPortName());
// If opened, temporarily close the connection so we can use
// it to download the firmware.
boolean wasOpened = target.isOpen();
if (wasOpened) {
arduinoTarget.pause();
}
StringBuffer cmdStr = new StringBuffer(uploadCmd[0]);
for (int i = 1; i < uploadCmd.length; ++i) {
cmdStr.append(' ');
cmdStr.append(uploadCmd[i]);
}
// Start the launch
((ArduinoLaunch) launch).start();
// Run the process and capture the results in the console
ProcessBuilder processBuilder = new ProcessBuilder(uploadCmd)
.directory(arduinoConfig.getBuildDirectory());
arduinoConfig.setEnvironment(processBuilder.environment());
Process process = processBuilder.start();
// Run the process and capture the results in the console
ProcessBuilder processBuilder = new ProcessBuilder(uploadCmd).directory(arduinoConfig.getBuildDirectory());
arduinoConfig.setEnvironment(processBuilder.environment());
Process process = processBuilder.start();
DebugPlugin.newProcess(launch, process, cmdStr.toString());
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
}
consoleService.monitor(process, null, null);
try {
process.waitFor();
} catch (InterruptedException e) {
}
consoleService.writeOutput("Upload complete\n");
// Reopen the connection
if (wasOpened) {
arduinoTarget.resume();
}
} catch (CoreException e) {
return e.getStatus();
} catch (IOException e) {
return new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e);
} finally {
DebugPlugin.getDefault().getLaunchManager().removeLaunch(launch);
}
return Status.OK_STATUS;
};
}.schedule();
}
}

View file

@ -10,21 +10,25 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.launch;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoProjectNature;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.debug.core.DebugPlugin;
import org.eclipse.debug.core.ILaunchConfiguration;
import org.eclipse.debug.core.ILaunchConfigurationType;
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
import org.eclipse.launchbar.core.ILaunchDescriptor;
import org.eclipse.launchbar.core.ProjectPerTargetLaunchConfigProvider;
import org.eclipse.launchbar.core.ProjectLaunchConfigProvider;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.remote.core.IRemoteConnection;
public class ArduinoLaunchConfigurationProvider extends ProjectPerTargetLaunchConfigProvider {
public class ArduinoLaunchConfigurationProvider extends ProjectLaunchConfigProvider {
@Override
public boolean supports(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
IRemoteConnection connection = target.getAdapter(IRemoteConnection.class);
if (connection != null) {
return connection.getConnectionType().getId().equals(ArduinoRemoteConnection.TYPE_ID);
}
return false;
}
@Override
public ILaunchConfigurationType getLaunchConfigurationType(ILaunchDescriptor descriptor, ILaunchTarget target)
@ -33,43 +37,4 @@ public class ArduinoLaunchConfigurationProvider extends ProjectPerTargetLaunchCo
.getLaunchConfigurationType(ArduinoLaunchConfigurationDelegate.TYPE_ID);
}
@Override
public boolean supports(ILaunchDescriptor descriptor, ILaunchTarget target) throws CoreException {
if (!super.supports(descriptor, target)) {
return false;
}
if (target != null && !target.getTypeId().equals(ArduinoRemoteConnection.TYPE_ID)) {
return false;
}
// must have the arduino nature
IProject project = descriptor.getAdapter(IProject.class);
return ArduinoProjectNature.hasNature(project);
}
@Override
protected void populateLaunchConfiguration(ILaunchDescriptor descriptor, ILaunchTarget target,
ILaunchConfigurationWorkingCopy workingCopy) throws CoreException {
super.populateLaunchConfiguration(descriptor, target, workingCopy);
if (target != null) {
workingCopy.setAttribute(ArduinoLaunchConfigurationDelegate.CONNECTION_NAME, target.getName());
}
}
@Override
protected ILaunchTarget getLaunchTarget(ILaunchConfiguration configuration) throws CoreException {
String name = configuration.getAttribute(ArduinoLaunchConfigurationDelegate.CONNECTION_NAME, ""); //$NON-NLS-1$
if (name.isEmpty()) {
return null;
}
ILaunchTargetManager manager = Activator.getService(ILaunchTargetManager.class);
return manager.getLaunchTarget(ArduinoRemoteConnection.TYPE_ID, name);
}
@Override
protected boolean providesForNullTarget() {
return true;
}
}

View file

@ -10,4 +10,9 @@ ArduinoBoardManager_1=Package index missing from response
ArduinoLaunchConfigurationDelegate_1=No active Arduino remote connection.
ArduinoLaunchConfigurationDelegate_0=Arduino Launch
ArduinoLaunchConfigurationDelegate_2=Target has not been selected for Launch Configuration
ArduinoManager_0=Install libraries
ArduinoManager_1=Installing libraries
ArduinoManager_2=Download failed, please try again.
ArduinoPlatform_0=Download failed, please try again.
ArduinoPlatform_1=Uninstall failed.
ArduinoProjectGenerator_0=Write Arduino project file

View file

@ -1,45 +0,0 @@
package org.eclipse.cdt.arduino.core.internal.remote;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.launchbar.core.target.ILaunchTargetProvider;
import org.eclipse.launchbar.core.target.TargetStatus;
import org.eclipse.launchbar.core.target.TargetStatus.Code;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
public class ArduinoLaunchTargetProvider implements ILaunchTargetProvider {
@Override
public void init(ILaunchTargetManager targetManager) {
IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType remoteType = remoteManager.getConnectionType(ArduinoRemoteConnection.TYPE_ID);
// remove any targets that don't have connections
for (ILaunchTarget target : targetManager.getLaunchTargetsOfType(ArduinoRemoteConnection.TYPE_ID)) {
if (remoteType.getConnection(target.getName()) == null) {
targetManager.removeLaunchTarget(target);
}
}
// add any targets that are missing
for (IRemoteConnection connection : remoteType.getConnections()) {
if (targetManager.getLaunchTarget(ArduinoRemoteConnection.TYPE_ID, connection.getName()) == null) {
targetManager.addLaunchTarget(ArduinoRemoteConnection.TYPE_ID, connection.getName());
}
}
}
@Override
public TargetStatus getStatus(ILaunchTarget target) {
ArduinoRemoteConnection connection = target.getAdapter(ArduinoRemoteConnection.class);
if (connection.getRemoteConnection().isOpen()) {
return TargetStatus.OK_STATUS;
} else {
return new TargetStatus(Code.ERROR, "Not connected");
}
}
}

View file

@ -31,10 +31,10 @@ public class ArduinoRemoteConnection
implements IRemoteConnectionPropertyService, IRemoteCommandShellService, IRemoteConnectionChangeListener {
public static final String TYPE_ID = "org.eclipse.cdt.arduino.core.connectionType"; //$NON-NLS-1$
public static final String PORT_NAME = "ardiuno.portname"; //$NON-NLS-1$
public static final String PACKAGE_NAME = "packageName"; //$NON-NLS-1$
public static final String PLATFORM_NAME = "platformName"; //$NON-NLS-1$
public static final String BOARD_NAME = "boardName"; //$NON-NLS-1$
public static final String PORT_NAME = "arduinoPortName"; //$NON-NLS-1$
public static final String PACKAGE_NAME = "arduinoPackageName"; //$NON-NLS-1$
public static final String PLATFORM_NAME = "arduinoPlatformName"; //$NON-NLS-1$
public static final String BOARD_NAME = "arduinoBoardName"; //$NON-NLS-1$
private final IRemoteConnection remoteConnection;
private SerialPort serialPort;
@ -95,7 +95,7 @@ public class ArduinoRemoteConnection
}
public ArduinoBoard getBoard() throws CoreException {
return ArduinoManager.instance.getBoard(remoteConnection.getAttribute(BOARD_NAME),
return Activator.getService(ArduinoManager.class).getBoard(remoteConnection.getAttribute(BOARD_NAME),
remoteConnection.getAttribute(PLATFORM_NAME), remoteConnection.getAttribute(PACKAGE_NAME));
}

View file

@ -1,40 +0,0 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.remote;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.launchbar.core.target.ILaunchTargetManager;
import org.eclipse.remote.core.IRemoteConnectionChangeListener;
import org.eclipse.remote.core.RemoteConnectionChangeEvent;
public class ArduinoRemoteConnectionListener implements IRemoteConnectionChangeListener {
public static ArduinoRemoteConnectionListener INSTANCE = new ArduinoRemoteConnectionListener();
@Override
public void connectionChanged(RemoteConnectionChangeEvent event) {
switch (event.getType()) {
case RemoteConnectionChangeEvent.CONNECTION_ADDED:
if (event.getConnection().getConnectionType().getId().equals(ArduinoRemoteConnection.TYPE_ID)) {
ILaunchTargetManager targetManager = Activator.getService(ILaunchTargetManager.class);
targetManager.addLaunchTarget(ArduinoRemoteConnection.TYPE_ID, event.getConnection().getName());
}
case RemoteConnectionChangeEvent.CONNECTION_REMOVED:
if (event.getConnection().getConnectionType().getId().equals(ArduinoRemoteConnection.TYPE_ID)) {
ILaunchTargetManager targetManager = Activator.getService(ILaunchTargetManager.class);
ILaunchTarget target = targetManager.getLaunchTarget(ArduinoRemoteConnection.TYPE_ID,
event.getConnection().getName());
if (target != null) {
targetManager.removeLaunchTarget(target);
}
}
}
}
}

View file

@ -1,35 +0,0 @@
package org.eclipse.cdt.arduino.core.internal.remote;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
public class ArduinoTargetAdapterFactory implements IAdapterFactory {
private IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class);
@Override
@SuppressWarnings("unchecked")
public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) {
if (adaptableObject instanceof ILaunchTarget) {
ILaunchTarget target = (ILaunchTarget) adaptableObject;
if (target.getTypeId().equals(ArduinoRemoteConnection.TYPE_ID)) {
IRemoteConnectionType connectionType = remoteManager.getConnectionType(target.getTypeId());
IRemoteConnection connection = connectionType.getConnection(target.getName());
if (connection != null) {
return (T) connection.getService(ArduinoRemoteConnection.class);
}
}
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class<?>[] { ArduinoRemoteConnection.class };
}
}

View file

@ -1,160 +0,0 @@
ifeq ($(BOARD),uno)
ARCH = avr
BUILD_CORE = arduino
BUILD_VARIANT = standard
BUILD_MCU = atmega328p
BUILD_F_CPU = 16000000L
BUILD_BOARD = AVR_UNO
LOADER = avrdude
LOADER_PROTOCOL = arduino
LOADER_SPEED = 115200
LOADER_MAX_SIZE = 32256
LOADER_MAX_DATA = 2048
endif
VERSION = 164
ifeq ($(ARCH),avr)
CXXFLAGS = -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD \
-mmcu=$(BUILD_MCU) -DF_CPU=$(BUILD_F_CPU) -DARDUINO=$(VERSION) -DARDUINO_$(BUILD_BOARD) -DARDUINO_ARCH_AVR $(INCLUDES)
CFLAGS = -g -Os -w -ffunction-sections -fdata-sections -MMD \
-mmcu=$(BUILD_MCU) -DF_CPU=$(BUILD_F_CPU) -DARDUINO=156 -DARDUINO_$(BUILD_BOARD) -DARDUINO_ARCH_AVR $(INCLUDES)
CXX = avr-g++
CC = avr-gcc
AR = avr-ar
OBJCOPY = avr-objcopy
define do_link
$(CC) -Os -Wl,--gc-sections -mmcu=$(BUILD_MCU) -o $(OUTPUT_DIR)/$(EXE).elf $^
avr-objcopy -O ihex -R .eeprom $(OUTPUT_DIR)/$(EXE).elf $(OUTPUT_DIR)/$(EXE).hex
$(do_link_extra)
avr-size $(OUTPUT_DIR)/$(EXE).elf
@echo Max text: $(LOADER_MAX_SIZE)
@echo Max data + bss: $(LOADER_MAX_DATA)
endef
define do_eeprom
avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load \
--no-change-warnings --change-section-lma .eeprom=0 \
$(OUTPUT_DIR)/$(EXE).elf $(OUTPUT_DIR)/$(EXE).eep
endef
define do_load_avrdude
avrdude -C"$(ARDUINO_HOME)/hardware/tools/avr/etc/avrdude.conf" -p$(BUILD_MCU) -c$(LOADER_PROTOCOL) \
-P$(SERIAL_PORT) -b$(LOADER_SPEED) -D "-Uflash:w:$(OUTPUT_DIR)/$(EXE).hex:i"
endef
endif # ARCH = avr
space :=
space +=
spacify = $(subst $(space),\$(space),$1)
ifeq ($(OS),Windows_NT)
RMDIR = rmdir /s /q
fixpath = $(subst /,\,$1)
mymkdir = if not exist "$(call fixpath,$1)" mkdir $(call fixpath,$1)
else
RMDIR = rm -fr
fixpath = $1
mymkdir = mkdir -p $1
endif
src_recurse = $(foreach d,$(subst $2/,,$(wildcard $1*)),$(call src_recurse,$3/$d/,$2,$3) $(filter %.c %.cpp,$d))
src = $(foreach lib,$3,$(if $(wildcard $2/$(lib)/src),$(call src_recurse,$2/$(lib)/src/,$1,$2),\
$(subst $1/,,\
$(wildcard $2/$(lib)/*.c)\
$(wildcard $2/$(lib)/*.cpp)\
$(wildcard $2/$(lib)/utility/*.c)\
$(wildcard $2/$(lib)/utility/*.cpp)))))
objs = $(patsubst %.c,$2/%.o,$(filter %.c,$1)) $(patsubst %.cpp,$2/%.o,$(filter %.cpp,$1))
incs = $(foreach lib,$1,$(if $(wildcard $3/$(lib)/src),-I"$2/$(lib)/src",-I"$2/$(lib)" -I"$2/$(lib)/utility"))
PROJECT_OBJS = $(call objs,$(call src_recurse,./,.,.),$(OUTPUT_DIR)/src)
LIB_ROOT = $(ARDUINO_HOME)/hardware/arduino/$(ARCH)/cores/$(BUILD_CORE)
LIB_ROOT_SPC = $(call spacify,$(LIB_ROOT))
LIB_ROOT_SPC2 = $(subst :,\:,$(subst \,\\\,$(LIB_ROOT_SPC)))
LIB_OBJS = $(call objs,$(call src_recurse,$(LIB_ROOT_SPC)/,$(LIB_ROOT),$(LIB_ROOT_SPC)),$(OUTPUT_DIR)/lib)
USER_LIB_ROOT = $(ARDUINO_USER_LIBS)
USER_LIB_ROOT_SPC = $(call spacify,$(USER_LIB_ROOT))
USER_LIB_ROOT_SPC2 = $(subst :,\:,$(subst \,\\\,$(USER_LIB_ROOT_SPC)))
USER_LIBS = $(foreach lib,$(LIBS),$(subst $(USER_LIB_ROOT)/,,$(wildcard $(USER_LIB_ROOT_SPC)/$(lib))))
USER_INCLUDES = $(call incs,$(USER_LIBS),$(USER_LIB_ROOT),$(USER_LIB_ROOT_SPC))
USER_OBJS = $(call objs,$(call src,$(USER_LIB_ROOT),$(USER_LIB_ROOT_SPC),$(USER_LIBS)),$(OUTPUT_DIR)/user)
HW_LIB_ROOT = $(ARDUINO_HOME)/hardware/arduino/$(ARCH)/libraries
HW_LIB_ROOT_SPC = $(call spacify,$(HW_LIB_ROOT))
HW_LIB_ROOT_SPC2 = $(subst :,\:,$(subst \,\\\,$(HW_LIB_ROOT_SPC)))
HW_LIBS = $(foreach lib, $(LIBS), $(subst $(HW_LIB_ROOT)/,,$(wildcard $(HW_LIB_ROOT_SPC)/$(lib))))
HW_INCLUDES = $(call incs,$(HW_LIBS),$(HW_LIB_ROOT),$(HW_LIB_ROOT_SPC))
HW_OBJS = $(call objs,$(call src,$(HW_LIB_ROOT),$(HW_LIB_ROOT_SPC),$(HW_LIBS)),$(OUTPUT_DIR)/hw)
ARDUINO_LIB_ROOT = $(ARDUINO_HOME)/libraries
ARDUINO_LIB_ROOT_SPC = $(call spacify,$(ARDUINO_LIB_ROOT))
ARDUINO_LIB_ROOT_SPC2 = $(subst :,\:,$(subst \,\\\,$(ARDUINO_LIB_ROOT_SPC)))
ARDUINO_LIBS = $(foreach lib, $(LIBS), $(subst $(ARDUINO_LIB_ROOT)/,,$(wildcard $(ARDUINO_LIB_ROOT_SPC)/$(lib))))
ARDUINO_INCLUDES = $(call incs,$(ARDUINO_LIBS),$(ARDUINO_LIB_ROOT),$(ARDUINO_LIB_ROOT_SPC))
ARDUINO_OBJS = $(call objs,$(call src,$(ARDUINO_LIB_ROOT),$(ARDUINO_LIB_ROOT_SPC),$(ARDUINO_LIBS)),$(OUTPUT_DIR)/arduino)
INCLUDES = -I"$(ARDUINO_HOME)/hardware/arduino/$(ARCH)/cores/$(BUILD_CORE)" \
-I"$(ARDUINO_HOME)/hardware/arduino/$(ARCH)/variants/$(BUILD_VARIANT)" \
$(USER_INCLUDES) $(HW_INCLUDES) $(ARDUINO_INCLUDES)
OBJS = $(PROJECT_OBJS) $(USER_OBJS) $(HW_OBJS) $(ARDUINO_OBJS)
all: $(OUTPUT_DIR)/$(EXE).hex
clean:
$(RMDIR) $(call fixpath,$(OUTPUT_DIR))
load: $(OUTPUT_DIR)/$(EXE).hex
$(do_load_$(LOADER))
$(OUTPUT_DIR)/$(EXE).hex: $(OBJS) $(OUTPUT_DIR)/core.a
$(do_link)
$(OUTPUT_DIR)/core.a: $(LIB_OBJS)
$(AR) r $@ $?
$(OUTPUT_DIR)/lib/%.o: $(LIB_ROOT_SPC2)/%.c
@-$(call mymkdir,$(dir $@))
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/lib/%.o: $(LIB_ROOT_SPC2)/%.cpp
@-$(call mymkdir,$(dir $@))
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/user/%.o: $(USER_LIB_ROOT_SPC2)/%.c
@-$(call mymkdir,$(dir $@))
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/user/%.o: $(USER_LIB_ROOT_SPC2)/%.cpp
@-$(call mymkdir,$(dir $@))
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/hw/%.o: $(HW_LIB_ROOT_SPC2)/%.c
@-$(call mymkdir,$(dir $@))
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/hw/%.o: $(HW_LIB_ROOT_SPC2)/%.cpp
@-$(call mymkdir,$(dir $@))
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/arduino/%.o: $(ARDUINO_LIB_ROOT_SPC2)/%.c
@-$(call mymkdir,$(dir $@))
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/arduino/%.o: $(ARDUINO_LIB_ROOT_SPC2)/%.cpp
@-$(call mymkdir,$(dir $@))
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ "$<"
$(OUTPUT_DIR)/src/%.o: %.c
@-$(call mymkdir,$(dir $@))
$(CC) -c $(CFLAGS) $(CPPFLAGS) -o $@ $<
$(OUTPUT_DIR)/src/%.o: %.cpp
@-$(call mymkdir,$(dir $@))
$(CXX) -c $(CXXFLAGS) $(CPPFLAGS) -o $@ $<

View file

@ -1,4 +1,5 @@
ifeq ($(OS),Windows_NT)
SHELL = $(ComSpec)
RMDIR = rmdir /s /q
mymkdir = if not exist "$1" mkdir "$1"
else
@ -10,7 +11,7 @@ PROJECT_OBJS = \
<#list project_srcs as file>
<#assign cpp = file?matches("(.*)\\.cpp")>
<#if cpp>
${build_path}/project/${cpp?groups[1]}.o \
${build_path}/project/${cpp?groups[1]}.cpp.o \
</#if>
</#list>
@ -18,34 +19,64 @@ PLATFORM_OBJS = \
<#list platform_srcs as file>
<#assign cpp = file?matches("${platform_path}/(.*)\\.cpp")>
<#if cpp>
${build_path}/platform/${cpp?groups[1]}.o \
${build_path}/platform/${cpp?groups[1]}.cpp.o \
</#if>
<#assign c = file?matches("${platform_path}/(.*)\\.c")>
<#if c>
${build_path}/platform/${c?groups[1]}.o \
${build_path}/platform/${c?groups[1]}.c.o \
</#if>
<#assign S = file?matches("${platform_path}/(.*)\\.S")>
<#if S>
${build_path}/platform/${S?groups[1]}.S.o \
</#if>
</#list>
LIBRARIES_OBJS = \
<#list libraries_srcs as file>
<#assign cpp = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.cpp")>
<#if !cpp>
<#assign cpp = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.cpp")>
</#if>
<#if cpp>
${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.o \
${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.o \
</#if>
<#assign c = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.c")>
<#if c>
${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.o \
<#if !c>
<#assign c = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.c")>
</#if>
</#list>
<#if c>
${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.o \
</#if>
</#list>
all: ${build_path}/${project_name}.hex ${build_path}/${project_name}.eep
TARGETS = \
<#if recipe_objcopy_hex_pattern??>
${build_path}/${project_name}.hex \
</#if>
<#if recipe_objcopy_epp_pattern??>
${build_path}/${project_name}.eep \
</#if>
<#if recipe_objcopy_bin_pattern??>
${build_path}/${project_name}.bin \
</#if>
all: $(TARGETS)
<#if recipe_objcopy_hex_pattern??>
${build_path}/${project_name}.hex: ${build_path}/${project_name}.elf
${recipe_objcopy_hex_pattern}
</#if>
<#if recipe_objcopy_epp_pattern??>
${build_path}/${project_name}.eep: ${build_path}/${project_name}.elf
${recipe_objcopy_eep_pattern}
</#if>
<#if recipe_objcopy_bin_pattern??>
${build_path}/${project_name}.bin: ${build_path}/${project_name}.elf
${recipe_objcopy_bin_pattern}
</#if>
${build_path}/${project_name}.elf: $(PROJECT_OBJS) $(LIBRARIES_OBJS) ${build_path}/core.a
${recipe_c_combine_pattern}
@ -60,45 +91,79 @@ size:
<#list project_srcs as file>
<#assign cpp = file?matches("(.*)\\.cpp")>
<#if cpp>
${build_path}/project/${cpp?groups[1]}.o: ../${file}
${build_path}/project/${cpp?groups[1]}.cpp.o: ../${file} ${build_path}/project/${cpp?groups[1]}.cpp.d
@$(call mymkdir,$(dir $@))
${recipe_cpp_o_pattern}
${build_path}/project/${cpp?groups[1]}.cpp.d: ;
-include ${build_path}/project/${cpp?groups[1]}.cpp.d
</#if>
</#list>
<#list platform_srcs as file>
<#assign cpp = file?matches("${platform_path}/(.*)\\.cpp")>
<#if cpp>
${build_path}/platform/${cpp?groups[1]}.o: ${file}
${build_path}/platform/${cpp?groups[1]}.cpp.o: ${file} ${build_path}/platform/${cpp?groups[1]}.cpp.d
@$(call mymkdir,$(dir $@))
${recipe_cpp_o_pattern}
${recipe_ar_pattern}
${build_path}/platform/${cpp?groups[1]}.cpp.d: ;
-include ${build_path}/platform/${cpp?groups[1]}.cpp.d
</#if>
<#assign c = file?matches("${platform_path}/(.*)\\.c")>
<#if c>
${build_path}/platform/${c?groups[1]}.o: ${file}
${build_path}/platform/${c?groups[1]}.c.o: ${file} ${build_path}/platform/${c?groups[1]}.c.d
@$(call mymkdir,$(dir $@))
${recipe_c_o_pattern}
${recipe_ar_pattern}
${build_path}/platform/${c?groups[1]}.c.d: ;
-include ${build_path}/platform/${c?groups[1]}.c.d
</#if>
<#assign S = file?matches("${platform_path}/(.*)\\.S")>
<#if S>
${build_path}/platform/${S?groups[1]}.S.o: ${file}
@$(call mymkdir,$(dir $@))
${recipe_S_o_pattern}
${recipe_ar_pattern}
</#if>
</#list>
<#list libraries_srcs as file>
<#assign cpp = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.cpp")>
<#if !cpp>
<#assign cpp = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.cpp")>
</#if>
<#if cpp>
${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.o: ${file}
${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.o: ${file} ${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d
@$(call mymkdir,$(dir $@))
${recipe_cpp_o_pattern}
${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d: ;
-include ${build_path}/libraries/${cpp?groups[1]}/${cpp?groups[2]}.cpp.d
</#if>
<#assign c = file?matches("${libraries_path}/(.*?)/.*?/(.*)\\.c")>
<#if !c>
<#assign c = file?matches("${platform_path}/libraries/(.*?)/(.*)\\.c")>
</#if>
<#if c>
${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.o: ${file}
${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.o: ${file} ${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.d
@$(call mymkdir,$(dir $@))
${recipe_c_o_pattern}
${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.d: ;
-include ${build_path}/libraries/${c?groups[1]}/${c?groups[2]}.c.d
</#if>
</#list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 551 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 564 B

View file

@ -30,6 +30,12 @@
project="true">
</wizard>
</extension>
<extension
point="org.eclipse.cdt.arduino.core.consoleService">
<provider
class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoConsole">
</provider>
</extension>
<extension
point="org.eclipse.ui.propertyPages">
<page
@ -38,10 +44,13 @@
name="Arduino"
selectionFilter="single">
<enabledWhen>
<adapt
type="org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection">
</adapt>
</enabledWhen>
<adapt type="org.eclipse.remote.core.IRemoteConnection">
<test
forcePluginActivation="false"
property="org.eclipse.cdt.arduino.ui.isArduinoRemote">
</test>
</adapt>
</enabledWhen>
</page>
<page
class="org.eclipse.cdt.arduino.ui.internal.project.LibrariesPropertyPage"
@ -89,12 +98,42 @@
id="org.eclipse.cdt.arduino.preference.page.boards"
name="Boards">
</page>
<page
category="org.eclipse.cdt.arduino.preference.page"
class="org.eclipse.cdt.arduino.ui.internal.preferences.ArduinoPlatformsPreferencePage"
id="org.eclipse.cdt.arduino.ui.page.platforms"
name="Platforms">
</page>
</extension>
<extension
point="org.eclipse.launchbar.ui.launchTargetTypeUI">
<launchTargetTypeUI
id="org.eclipse.cdt.arduino.core.connectionType"
labelProvider="org.eclipse.cdt.arduino.ui.internal.remote.ArduinoLaunchTargetLabelProvider">
</launchTargetTypeUI>
point="org.eclipse.ui.perspectiveExtensions">
<perspectiveExtension
targetID="org.eclipse.cdt.ui.CPerspective">
<view
id="org.eclipse.remote.ui.view.connections"
minimized="false"
ratio="0.75"
relationship="bottom"
relative="org.eclipse.ui.navigator.ProjectExplorer">
</view>
</perspectiveExtension>
</extension>
<extension
point="org.eclipse.core.expressions.propertyTesters">
<propertyTester
class="org.eclipse.cdt.arduino.ui.internal.project.ArduinoPropertyTester"
id="temporaryRemoteTester"
namespace="org.eclipse.cdt.arduino.ui"
properties="isArduinoRemote"
type="org.eclipse.remote.core.IRemoteConnection">
</propertyTester>
</extension>
<extension
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
<launchConfigurationTabGroup
class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoLaunchConfigurationTabGroup"
id="org.eclipse.cdt.arduino.ui.launchConfigurationTabGroup"
type="org.eclipse.cdt.arduino.core.launchConfigurationType">
</launchConfigurationTabGroup>
</extension>
</plugin>

View file

@ -29,6 +29,8 @@ public class Activator extends AbstractUIPlugin {
public static final String IMG_ARDUINO = PLUGIN_ID + ".arduino"; //$NON-NLS-1$
public static final String IMG_CONNECTION_TYPE = PLUGIN_ID + ".connectionType"; //$NON-NLS-1$
public static final String IMG_ADD = PLUGIN_ID + ".add";
public static final String IMG_DELETE = PLUGIN_ID + ".delete";
// The shared instance
private static Activator plugin;
@ -37,7 +39,7 @@ public class Activator extends AbstractUIPlugin {
super.start(context);
plugin = this;
// Load up the Arduino indices
ArduinoManager.instance.loadIndices();
getService(ArduinoManager.class).loadIndices();
}
public void stop(BundleContext context) throws Exception {
@ -50,6 +52,8 @@ public class Activator extends AbstractUIPlugin {
ImageRegistry registry = super.createImageRegistry();
registry.put(IMG_ARDUINO, imageDescriptorFromPlugin(PLUGIN_ID, "icons/cprojects.gif")); //$NON-NLS-1$
registry.put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arduino.png")); //$NON-NLS-1$
registry.put(IMG_ADD, imageDescriptorFromPlugin(PLUGIN_ID, "icons/list-add.gif")); //$NON-NLS-1$
registry.put(IMG_DELETE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/list-delete.gif")); //$NON-NLS-1$
return registry;
}

View file

@ -25,8 +25,28 @@ public class Messages extends NLS {
public static String NewArduinoTargetWizardPage_4;
public static String NewArduinoTargetWizardPage_5;
public static String ArduinoBoardsPreferencePage_desc;
public static String LibrariesPropertyPage_0;
public static String LibrariesPropertyPage_1;
public static String LibrariesPropertyPage_desc;
public static String ArduinoPlatformsPreferencePage_0;
public static String ArduinoPlatformsPreferencePage_1;
public static String ArduinoPlatformsPreferencePage_10;
public static String ArduinoPlatformsPreferencePage_11;
public static String ArduinoPlatformsPreferencePage_12;
public static String ArduinoPlatformsPreferencePage_13;
public static String ArduinoPlatformsPreferencePage_14;
public static String ArduinoPlatformsPreferencePage_15;
public static String ArduinoPlatformsPreferencePage_2;
public static String ArduinoPlatformsPreferencePage_3;
public static String ArduinoPlatformsPreferencePage_4;
public static String ArduinoPlatformsPreferencePage_5;
public static String ArduinoPlatformsPreferencePage_6;
public static String ArduinoPlatformsPreferencePage_7;
public static String ArduinoPlatformsPreferencePage_8;
public static String ArduinoPlatformsPreferencePage_9;
public static String ArduinoPreferencePage_desc;
public static String PlatformDetailsDialog_0;
public static String PlatformDetailsDialog_1;
static {
// initialize resource bundle

View file

@ -0,0 +1,162 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.launch;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IResourceChangeEvent;
import org.eclipse.core.resources.IResourceChangeListener;
import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.swt.SWT;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.console.ConsolePlugin;
import org.eclipse.ui.console.IConsole;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.console.MessageConsoleStream;
public class ArduinoConsole implements ArduinoConsoleService, IResourceChangeListener {
private static MessageConsole console;
private static MessageConsoleStream out;
private static MessageConsoleStream err;
private IFolder buildDirectory;
List<ArduinoPatternMatchListener> listeners = new ArrayList<>();
public ArduinoConsole() {
if (console == null) {
console = new MessageConsole(Messages.ArduinoLaunchConsole_0, null);
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
out = console.newMessageStream();
err = console.newMessageStream();
// set the colors
final Display display = Display.getDefault();
display.syncExec(new Runnable() {
@Override
public void run() {
out.setColor(display.getSystemColor(SWT.COLOR_BLACK));
err.setColor(display.getSystemColor(SWT.COLOR_RED));
}
});
ResourcesPlugin.getWorkspace().addResourceChangeListener(this, IResourceChangeEvent.PRE_BUILD);
}
}
@Override
public void resourceChanged(IResourceChangeEvent event) {
switch (event.getType()) {
case IResourceChangeEvent.PRE_BUILD:
if (event.getBuildKind() != IncrementalProjectBuilder.AUTO_BUILD) {
// TODO this really should be done from the core and only when
// our projects are being built
console.clearConsole();
}
break;
}
}
public IFolder getBuildDirectory() {
return buildDirectory;
}
@Override
public void monitor(final Process process, ArduinoConsoleParser[] consoleParsers, IFolder buildDirectory)
throws IOException {
this.buildDirectory = buildDirectory;
// Clear the old listeners
for (ArduinoPatternMatchListener listener : listeners) {
console.removePatternMatchListener(listener);
}
listeners.clear();
// Add in the new ones if any
if (consoleParsers != null) {
for (ArduinoConsoleParser parser : consoleParsers) {
ArduinoPatternMatchListener listener;
if (parser instanceof ArduinoErrorParser) {
listener = new ArduinoErrorMatchListener(this, (ArduinoErrorParser) parser);
} else {
continue;
}
listeners.add(listener);
console.addPatternMatchListener(listener);
}
}
console.activate();
final Semaphore sema = new Semaphore(-1);
// Output stream reader
new Thread(Messages.ArduinoLaunchConsole_2) {
public void run() {
try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) {
for (String line = processOut.readLine(); line != null; line = processOut.readLine()) {
out.write(line);
out.write('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
sema.release();
}
}
}.start();
// Error stream reader
new Thread(Messages.ArduinoLaunchConsole_2) {
public void run() {
try (BufferedReader processErr = new BufferedReader(new InputStreamReader(process.getErrorStream()))) {
for (String line = processErr.readLine(); line != null; line = processErr.readLine()) {
err.write(line);
out.write('\n');
}
} catch (IOException e) {
e.printStackTrace();
} finally {
sema.release();
}
}
}.start();
try {
sema.acquire();
process.waitFor();
} catch (InterruptedException e) {
Activator.log(e);
}
}
@Override
public void writeOutput(String msg) throws IOException {
out.write(msg);
}
@Override
public void writeError(String msg) throws IOException {
err.write(msg);
}
}

View file

@ -0,0 +1,38 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.launch;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoErrorParser;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.core.resources.IMarker;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.ui.console.PatternMatchEvent;
public class ArduinoErrorMatchListener extends ArduinoPatternMatchListener {
public ArduinoErrorMatchListener(ArduinoConsole arduinoConsole, ArduinoErrorParser parser) {
super(arduinoConsole, parser);
}
@Override
public void matchFound(PatternMatchEvent event) {
try {
String text = textConsole.getDocument().get(event.getOffset(), event.getLength());
IMarker marker = ((ArduinoErrorParser) parser).generateMarker(arduinoConsole.getBuildDirectory(), text);
if (marker != null) {
textConsole.addHyperlink(new ArduinoHyperlink(marker),
event.getOffset() + marker.getAttribute(ArduinoErrorParser.LINK_OFFSET, 0),
marker.getAttribute(ArduinoErrorParser.LINK_LENGTH, event.getLength()));
}
} catch (BadLocationException | CoreException e) {
Activator.log(e);
}
}
}

View file

@ -0,0 +1,44 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.launch;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.core.resources.IMarker;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.console.IHyperlink;
import org.eclipse.ui.ide.IDE;
public class ArduinoHyperlink implements IHyperlink {
private final IMarker marker;
public ArduinoHyperlink(IMarker marker) {
this.marker = marker;
}
@Override
public void linkEntered() {
}
@Override
public void linkExited() {
}
@Override
public void linkActivated() {
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
IDE.openEditor(page, marker);
} catch (PartInitException e) {
Activator.log(e);
}
}
}

View file

@ -0,0 +1,24 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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:
* QNX Software Systems - Initial API and implementation
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.launch;
import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
import org.eclipse.debug.ui.ILaunchConfigurationTab;
public class ArduinoLaunchConfigurationTabGroup extends AbstractLaunchConfigurationTabGroup {
@Override
public void createTabs(ILaunchConfigurationDialog dialog, String mode) {
setTabs(new ILaunchConfigurationTab[0]);
}
}

View file

@ -0,0 +1,50 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.launch;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleParser;
import org.eclipse.ui.console.IPatternMatchListener;
import org.eclipse.ui.console.TextConsole;
public abstract class ArduinoPatternMatchListener implements IPatternMatchListener {
protected final ArduinoConsole arduinoConsole;
protected final ArduinoConsoleParser parser;
protected TextConsole textConsole;
public ArduinoPatternMatchListener(ArduinoConsole arduinoConsole, ArduinoConsoleParser parser) {
this.arduinoConsole = arduinoConsole;
this.parser = parser;
}
@Override
public void connect(TextConsole console) {
this.textConsole = console;
}
@Override
public void disconnect() {
}
@Override
public String getPattern() {
return parser.getPattern();
}
@Override
public int getCompilerFlags() {
return parser.getCompilerFlags();
}
@Override
public String getLineQualifier() {
return parser.getLineQualifier();
}
}

View file

@ -1,10 +1,10 @@
################################################################################
#******************************************************************************
# Copyright (c) 2015 QNX Software Systems 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
################################################################################
#******************************************************************************
ArduinoLaunchConsole_0=Arduino
ArduinoLaunchConsole_1=Start Arduino Console
ArduinoLaunchConsole_2=Arduino Console Output
@ -18,10 +18,29 @@ NewArduinoTargetWizardPage_2=Target name:
NewArduinoTargetWizardPage_3=
NewArduinoTargetWizardPage_4=Serial port:
NewArduinoTargetWizardPage_5=Board type:
ArduinoBoardsPreferencePage_desc=Select a board you would like to install and click Install and then \
OK or Apply to install the SDK and Tools for that board. By doing so you agree to the licenses of the \
libraries and tools. For more information, see http://arduino.cc.
ArduinoBoardsPreferencePage_desc=NOTE: To install support for an Arduino board, please use the Arduino \
Platforms preference page to install the platform support for that board.
LibrariesPropertyPage_0=Name
LibrariesPropertyPage_1=Description
LibrariesPropertyPage_desc=Select libraries to use in your project and click OK or Apply. \
If necessary the library will be installed. By adding libraries you agree to the licenses of those \
libraries. For more information, see http://arduino.cc
ArduinoPreferencePage_desc=Enter URLs for package_index.json files one per line.
ArduinoPlatformsPreferencePage_0=Select a platform then click a button to install, uninstall, or find more details about the platform.
ArduinoPlatformsPreferencePage_1=Platform
ArduinoPlatformsPreferencePage_10=Information on the licenses can be found at arduino.cc web site.
ArduinoPlatformsPreferencePage_11=Arduino License
ArduinoPlatformsPreferencePage_12=Accept
ArduinoPlatformsPreferencePage_13=Decline
ArduinoPlatformsPreferencePage_14=Installing Arduino Board Platforms
ArduinoPlatformsPreferencePage_15=Installing Arduino Board Platforms
ArduinoPlatformsPreferencePage_2=Installed
ArduinoPlatformsPreferencePage_3=Available
ArduinoPlatformsPreferencePage_4=Install
ArduinoPlatformsPreferencePage_5=Upgrade
ArduinoPlatformsPreferencePage_6=Details
ArduinoPlatformsPreferencePage_7=Install
ArduinoPlatformsPreferencePage_8=Uninstall
ArduinoPlatformsPreferencePage_9=Do you accept the licenses for the Arduino SDK and libraries?
ArduinoPreferencePage_desc=Enter URLs for package_index.json files one per line.
PlatformDetailsDialog_0=Platform:
PlatformDetailsDialog_1=Supports boards:\n

View file

@ -7,46 +7,19 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.preferences;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
public class ArduinoBoardsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private Table table;
private Button installButton;
private Set<ArduinoBoard> toInstall = new HashSet<>();
@Override
public void init(IWorkbench workbench) {
}
@ -63,150 +36,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
desc.setBackground(parent.getBackground());
desc.setText(Messages.ArduinoBoardsPreferencePage_desc);
Composite comp = new Composite(control, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = 0;
comp.setLayout(layout);
comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Composite tableComp = new Composite(comp, SWT.NONE);
tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table = new Table(tableComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn packageColumn = new TableColumn(table, SWT.LEAD);
packageColumn.setText("Board");
TableColumn platformColumn = new TableColumn(table, SWT.LEAD);
platformColumn.setText("Platform");
TableColumn installedColumn = new TableColumn(table, SWT.LEAD);
installedColumn.setText("Installed");
TableColumnLayout tableLayout = new TableColumnLayout();
tableLayout.setColumnData(packageColumn, new ColumnWeightData(5, 150, true));
tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true));
tableLayout.setColumnData(installedColumn, new ColumnWeightData(2, 75, true));
tableComp.setLayout(tableLayout);
table.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
updateButtons();
}
});
Composite buttonComp = new Composite(comp, SWT.NONE);
buttonComp.setLayout(new GridLayout());
buttonComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
installButton = new Button(buttonComp, SWT.PUSH);
installButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
installButton.setText("Install");
installButton.addListener(SWT.Selection, new Listener() {
@Override
public void handleEvent(Event event) {
for (TableItem item : table.getSelection()) {
ArduinoBoard board = (ArduinoBoard) item.getData();
toInstall.add(board);
item.setText(2, "selected");
updateButtons();
}
}
});
updateTable();
updateButtons();
return control;
}
private void updateTable() {
if (table == null || table.isDisposed()) {
return;
}
table.removeAll();
try {
List<ArduinoBoard> boards = ArduinoManager.instance.getBoards();
Collections.sort(boards, new Comparator<ArduinoBoard>() {
public int compare(ArduinoBoard o1, ArduinoBoard o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (ArduinoBoard board : boards) {
TableItem item = new TableItem(table, SWT.NONE);
item.setData(board);
item.setText(0, board.getName());
item.setText(1, board.getPlatform().getName());
String msg;
if (toInstall.contains(board)) {
msg = "selected";
} else {
msg = board.getPlatform().isInstalled() ? "yes" : "no";
}
item.setText(2, msg);
}
} catch (CoreException e) {
Activator.log(e);
}
}
private void updateButtons() {
if (table == null || table.isDisposed()) {
return;
}
boolean enable = false;
for (TableItem item : table.getSelection()) {
ArduinoBoard board = (ArduinoBoard) item.getData();
if (toInstall.contains(board)) {
continue;
}
ArduinoPlatform platform = board.getPlatform();
if (!platform.isInstalled()) {
enable = true;
}
}
installButton.setEnabled(enable);
}
@Override
public boolean performOk() {
new Job("Installing Arduino Board Platforms") {
@Override
protected IStatus run(IProgressMonitor monitor) {
Set<ArduinoPlatform> platforms = new HashSet<>();
for (ArduinoBoard board : toInstall) {
platforms.add(board.getPlatform());
}
MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, 0, "Installing Arduino Board Platforms",
null);
for (ArduinoPlatform platform : platforms) {
status.add(platform.install(monitor));
}
toInstall.clear();
if (table != null && !table.isDisposed()) {
table.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
updateTable();
}
});
}
return status;
}
}.schedule();
return true;
}
}

View file

@ -0,0 +1,264 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.preferences;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.board.PackageIndex;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.jface.viewers.ColumnWeightData;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.IWorkbenchPreferencePage;
public class ArduinoPlatformsPreferencePage extends PreferencePage implements IWorkbenchPreferencePage {
private Table table;
private Button installButton;
private Button uninstallButton;
private Button detailButton;
private Collection<ArduinoPlatform> toInstall = new HashSet<>();
private Collection<ArduinoPlatform> toUninstall = new HashSet<>();
private static ArduinoManager manager = Activator.getService(ArduinoManager.class);
@Override
public void init(IWorkbench workbench) {
}
@Override
protected Control createContents(Composite parent) {
Composite control = new Composite(parent, SWT.NONE);
control.setLayout(new GridLayout());
Text desc = new Text(control, SWT.READ_ONLY | SWT.WRAP);
GridData layoutData = new GridData(SWT.FILL, SWT.FILL, true, false);
layoutData.widthHint = 500;
desc.setLayoutData(layoutData);
desc.setBackground(parent.getBackground());
desc.setText(Messages.ArduinoPlatformsPreferencePage_0);
Composite comp = new Composite(control, SWT.NONE);
GridLayout layout = new GridLayout(2, false);
layout.marginWidth = 0;
comp.setLayout(layout);
comp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Composite tableComp = new Composite(comp, SWT.NONE);
tableComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table = new Table(tableComp, SWT.SINGLE | SWT.BORDER | SWT.V_SCROLL | SWT.FULL_SELECTION);
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
table.setHeaderVisible(true);
table.setLinesVisible(true);
TableColumn platformColumn = new TableColumn(table, SWT.LEAD);
platformColumn.setText(Messages.ArduinoPlatformsPreferencePage_1);
TableColumn installedColumn = new TableColumn(table, SWT.LEAD);
installedColumn.setText(Messages.ArduinoPlatformsPreferencePage_2);
TableColumn availableColumn = new TableColumn(table, SWT.LEAD);
availableColumn.setText(Messages.ArduinoPlatformsPreferencePage_3);
TableColumnLayout tableLayout = new TableColumnLayout();
tableLayout.setColumnData(platformColumn, new ColumnWeightData(5, 150, true));
tableLayout.setColumnData(installedColumn, new ColumnWeightData(2, 75, true));
tableLayout.setColumnData(availableColumn, new ColumnWeightData(2, 75, true));
tableComp.setLayout(tableLayout);
table.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
TableItem[] selection = table.getSelection();
if (selection.length > 0) {
TableItem item = selection[0];
detailButton.setEnabled(true);
ArduinoPlatform aplat = (ArduinoPlatform) item.getData();
ArduinoPlatform iplat = aplat.getPackage().getInstalledPlatforms().get(aplat.getName());
if (iplat == null) {
installButton.setEnabled(true);
installButton.setText(Messages.ArduinoPlatformsPreferencePage_4);
uninstallButton.setEnabled(false);
} else {
installButton.setText(Messages.ArduinoPlatformsPreferencePage_5);
if (!aplat.getVersion().equals(iplat.getVersion())) {
// Assuming upgrade if not equal, dangerous
installButton.setEnabled(true);
} else {
installButton.setEnabled(false);
}
uninstallButton.setEnabled(true);
}
} else {
detailButton.setEnabled(false);
installButton.setEnabled(false);
uninstallButton.setEnabled(false);
}
}
});
Composite buttonComp = new Composite(comp, SWT.NONE);
buttonComp.setLayout(new GridLayout());
buttonComp.setLayoutData(new GridData(SWT.BEGINNING, SWT.BEGINNING, false, false));
detailButton = new Button(buttonComp, SWT.PUSH);
detailButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
detailButton.setText(Messages.ArduinoPlatformsPreferencePage_6);
detailButton.setEnabled(false);
detailButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
TableItem[] selection = table.getSelection();
// We are only enabled when there is a selection
ArduinoPlatform platform = (ArduinoPlatform) selection[0].getData();
PlatformDetailsDialog dialog = new PlatformDetailsDialog(getShell(), platform);
dialog.open();
}
});
installButton = new Button(buttonComp, SWT.PUSH);
installButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
installButton.setText(Messages.ArduinoPlatformsPreferencePage_7);
installButton.setEnabled(false);
installButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
TableItem[] selection = table.getSelection();
if (selection.length > 0) {
TableItem item = selection[0];
toInstall.add(((ArduinoPlatform) item.getData()));
item.setImage(Activator.getDefault().getImageRegistry().get(Activator.IMG_ADD));
}
}
});
uninstallButton = new Button(buttonComp, SWT.PUSH);
uninstallButton.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
uninstallButton.setText(Messages.ArduinoPlatformsPreferencePage_8);
uninstallButton.setEnabled(false);
uninstallButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
TableItem[] selection = table.getSelection();
if (selection.length > 0) {
TableItem item = selection[0];
toUninstall.add(((ArduinoPlatform) item.getData()));
item.setImage(Activator.getDefault().getImageRegistry().get(Activator.IMG_DELETE));
}
}
});
populateTable();
return control;
}
private void populateTable() {
table.removeAll();
for (PackageIndex packageIndex : manager.getPackageIndices()) {
for (ArduinoPackage pkg : packageIndex.getPackages()) {
Map<String, ArduinoPlatform> available = pkg.getAvailablePlatforms();
Map<String, ArduinoPlatform> installed = pkg.getInstalledPlatforms();
List<String> names = new ArrayList<>(available.keySet());
Collections.sort(names);
for (String name : names) {
TableItem item = new TableItem(table, SWT.NONE);
item.setText(0, name);
ArduinoPlatform iplat = installed.get(name);
item.setText(1, iplat != null ? iplat.getVersion() : "---"); //$NON-NLS-1$
ArduinoPlatform aplat = available.get(name);
item.setText(2, aplat.getVersion());
item.setData(aplat);
}
}
}
}
@Override
public boolean performOk() {
File acceptedFile = ArduinoPreferences.getArduinoHome().resolve(".accepted").toFile(); //$NON-NLS-1$
if (!acceptedFile.exists()) {
String message = Messages.ArduinoPlatformsPreferencePage_9 + Messages.ArduinoPlatformsPreferencePage_10;
MessageDialog dialog = new MessageDialog(getShell(),
Messages.ArduinoPlatformsPreferencePage_11, null, message, MessageDialog.QUESTION, new String[] {
Messages.ArduinoPlatformsPreferencePage_12, Messages.ArduinoPlatformsPreferencePage_13 },
0);
int rc = dialog.open();
if (rc == 0) {
try {
acceptedFile.createNewFile();
} catch (IOException e) {
Activator.log(e);
}
} else {
return false;
}
}
new Job(Messages.ArduinoPlatformsPreferencePage_14) {
@Override
protected IStatus run(IProgressMonitor monitor) {
MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, 0, Messages.ArduinoPlatformsPreferencePage_15,
null);
for (ArduinoPlatform platform : toUninstall) {
status.add(platform.uninstall(monitor));
}
toUninstall.clear();
for (ArduinoPlatform platform : toInstall) {
status.add(platform.install(monitor));
}
toInstall.clear();
if (table != null && !table.isDisposed()) {
table.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
populateTable();
}
});
}
return status;
}
}.schedule();
return true;
}
}

View file

@ -12,6 +12,7 @@ package org.eclipse.cdt.arduino.ui.internal.preferences;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.jface.preference.PreferencePage;
import org.eclipse.swt.SWT;
@ -43,7 +44,7 @@ public class ArduinoPreferencePage extends PreferencePage implements IWorkbenchP
desc.setBackground(parent.getBackground());
desc.setText(Messages.ArduinoPreferencePage_desc);
urlsText = new Text(control, SWT.BORDER);
urlsText = new Text(control, SWT.BORDER | SWT.MULTI);
urlsText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
urlsText.setText(ArduinoPreferences.getBoardUrls());
@ -53,7 +54,7 @@ public class ArduinoPreferencePage extends PreferencePage implements IWorkbenchP
@Override
public boolean performOk() {
ArduinoPreferences.setBoardUrls(urlsText.getText());
ArduinoManager.instance.loadIndices();
Activator.getService(ArduinoManager.class).loadIndices();
return true;
}

View file

@ -0,0 +1,72 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.preferences;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.dialogs.IDialogConstants;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
public class PlatformDetailsDialog extends Dialog {
private final ArduinoPlatform platform;
protected PlatformDetailsDialog(Shell parentShell, ArduinoPlatform platform) {
super(parentShell);
setShellStyle(getShellStyle() | SWT.RESIZE);
this.platform = platform;
}
@Override
protected Control createDialogArea(Composite parent) {
Composite control = (Composite) super.createDialogArea(parent);
Text text = new Text(control, SWT.BORDER | SWT.READ_ONLY | SWT.MULTI | SWT.V_SCROLL);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
StringBuilder str = new StringBuilder();
str.append(Messages.PlatformDetailsDialog_0);
str.append(platform.getName());
str.append('\n');
str.append(Messages.PlatformDetailsDialog_1);
List<ArduinoBoard> boards = platform.getBoards();
Collections.sort(boards, new Comparator<ArduinoBoard>() {
@Override
public int compare(ArduinoBoard o1, ArduinoBoard o2) {
return o1.getName().compareTo(o2.getName());
}
});
for (ArduinoBoard board : platform.getBoards()) {
str.append(" "); //$NON-NLS-1$
str.append(board.getName());
str.append('\n');
}
text.setText(str.toString());
return control;
}
@Override
protected void createButtonsForButtonBar(Composite parent) {
createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
}
}

View file

@ -0,0 +1,26 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.project;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.core.expressions.PropertyTester;
import org.eclipse.remote.core.IRemoteConnection;
public class ArduinoPropertyTester extends PropertyTester {
@Override
public boolean test(Object receiver, String property, Object[] args, Object expectedValue) {
if (receiver instanceof IRemoteConnection) {
IRemoteConnection remote = (IRemoteConnection) receiver;
return remote.hasService(ArduinoRemoteConnection.class);
} else {
return false;
}
}
}

View file

@ -9,11 +9,15 @@ package org.eclipse.cdt.arduino.ui.internal.project;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoLibrary;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.board.LibraryIndex;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.resources.IProject;
@ -40,7 +44,9 @@ import org.eclipse.ui.dialogs.PropertyPage;
public class LibrariesPropertyPage extends PropertyPage {
private static class ContentProvider implements ITreeContentProvider {
private static ArduinoManager manager = Activator.getService(ArduinoManager.class);
private class ContentProvider implements ITreeContentProvider {
private LibraryIndex index;
@Override
@ -55,9 +61,9 @@ public class LibrariesPropertyPage extends PropertyPage {
@Override
public boolean hasChildren(Object element) {
if (element instanceof LibraryIndex) {
return !index.getCategories().isEmpty();
return true;
} else if (element instanceof String) { // category
return !index.getLibraries((String) element).isEmpty();
return true;
} else if (element instanceof ArduinoLibrary) {
return false;
} else {
@ -68,8 +74,10 @@ public class LibrariesPropertyPage extends PropertyPage {
@Override
public Object getParent(Object element) {
if (element instanceof ArduinoLibrary) {
return ((ArduinoLibrary) element).getCategory();
} else if (element instanceof String) {
ArduinoLibrary lib = (ArduinoLibrary) element;
String category = lib.getCategory();
return category != null ? category : LibraryIndex.UNCATEGORIZED;
} else if (element instanceof String || element instanceof ArduinoPlatform) {
return index;
} else {
return null;
@ -78,15 +86,46 @@ public class LibrariesPropertyPage extends PropertyPage {
@Override
public Object[] getElements(Object inputElement) {
return ((LibraryIndex) inputElement).getCategories().toArray(new String[0]);
Set<String> categories = new HashSet<>();
categories.addAll(((LibraryIndex) inputElement).getCategories());
try {
for (ArduinoLibrary lib : getPlatform().getLibraries()) {
String category = lib.getCategory();
categories.add(category != null ? category : LibraryIndex.UNCATEGORIZED);
}
} catch (CoreException e) {
Activator.log(e);
}
return categories.toArray();
}
@Override
public Object[] getChildren(Object parentElement) {
if (parentElement instanceof String) {
return index.getLibraries((String) parentElement).toArray(new ArduinoLibrary[0]);
String category = (String) parentElement;
List<ArduinoLibrary> libs = new ArrayList<>();
libs.addAll(index.getLibraries(category));
try {
for (ArduinoLibrary lib : getPlatform().getLibraries()) {
String cat = lib.getCategory();
if (cat != null) {
if (cat.equals(category)) {
libs.add(lib);
}
} else if (category.equals(LibraryIndex.UNCATEGORIZED)) { // cat
// ==
// null
libs.add(lib);
}
}
} catch (CoreException e) {
Activator.log(e);
}
return libs.toArray();
} else {
return null;
return new Object[0];
}
}
}
@ -146,6 +185,7 @@ public class LibrariesPropertyPage extends PropertyPage {
}
}
}, true) {
@Override
protected TreeViewer doCreateTreeViewer(Composite parent, int style) {
return new ContainerCheckedTreeViewer(parent, style);
@ -158,28 +198,36 @@ public class LibrariesPropertyPage extends PropertyPage {
Tree tree = viewer.getTree();
tree.setHeaderVisible(true);
TreeColumn column1 = new TreeColumn(tree, SWT.LEFT);
column1.setText("Name");
column1.setText(Messages.LibrariesPropertyPage_0);
column1.setWidth(200);
TreeColumn column2 = new TreeColumn(tree, SWT.LEFT);
column2.setText("Description");
column2.setText(Messages.LibrariesPropertyPage_1);
column2.setWidth(200);
viewer.setContentProvider(new ContentProvider());
viewer.setLabelProvider(new LabelProvider());
try {
viewer.setInput(ArduinoManager.instance.getLibraryIndex());
viewer.setInput(manager.getLibraryIndex());
// Set the check states for currently selected libraries
IProject project = getElement().getAdapter(IProject.class);
Collection<ArduinoLibrary> libraries = ArduinoManager.instance.getLibraries(project);
Collection<ArduinoLibrary> libraries = manager.getLibraries(project);
for (ArduinoLibrary lib : libraries) {
viewer.setChecked(lib, true);
}
} catch (CoreException e) {
Activator.log(e);
}
return comp;
}
private IProject getProject() {
return getElement().getAdapter(IProject.class);
}
private ArduinoPlatform getPlatform() throws CoreException {
return getProject().getActiveBuildConfig().getAdapter(ArduinoBuildConfiguration.class).getBoard().getPlatform();
}
@Override
@ -194,7 +242,7 @@ public class LibrariesPropertyPage extends PropertyPage {
}
}
try {
ArduinoManager.instance.setLibraries(getElement().getAdapter(IProject.class), libs);
manager.setLibraries(getProject(), libs);
} catch (CoreException e) {
Activator.log(e);
}

View file

@ -33,10 +33,11 @@ public class NewArduinoProjectWizard extends BasicNewProjectResourceWizard {
return false;
new Job(Messages.NewArduinoProjectWizard_0) {
@Override
protected IStatus run(IProgressMonitor monitor) {
try {
final ArduinoProjectGenerator generator = new ArduinoProjectGenerator(getNewProject());
generator.setupArduinoProject(monitor);
generator.generate(monitor);
getWorkbench().getDisplay().asyncExec(new Runnable() {
@Override
public void run() {

View file

@ -1,28 +0,0 @@
package org.eclipse.cdt.arduino.ui.internal.remote;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.launchbar.core.target.ILaunchTarget;
import org.eclipse.swt.graphics.Image;
public class ArduinoLaunchTargetLabelProvider extends LabelProvider {
@Override
public String getText(Object element) {
if (element instanceof ILaunchTarget) {
return ((ILaunchTarget) element).getName();
}
return super.getText(element);
}
@Override
public Image getImage(Object element) {
if (element instanceof ILaunchTarget
&& ((ILaunchTarget) element).getTypeId().equals(ArduinoRemoteConnection.TYPE_ID)) {
return Activator.getDefault().getImageRegistry().get(Activator.IMG_ARDUINO);
}
return super.getImage(element);
}
}

View file

@ -44,36 +44,24 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(2, false));
IRemoteConnection remoteConnection = (IRemoteConnection) getElement().getAdapter(IRemoteConnection.class);
IRemoteConnection remoteConnection = getElement().getAdapter(IRemoteConnection.class);
ArduinoRemoteConnection arduinoRemote = remoteConnection.getService(ArduinoRemoteConnection.class);
Label portLabel = new Label(comp, SWT.NONE);
portLabel.setText(Messages.ArduinoTargetPropertyPage_0);
portSelector = new Combo(comp, SWT.READ_ONLY);
portSelector = new Combo(comp, SWT.NONE);
portSelector.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
String currentPort = arduinoRemote.getPortName();
int i = 0, portSel = -1;
portSelector.setText(currentPort);
try {
for (String port : SerialPort.list()) {
portSelector.add(port);
if (port.equals(currentPort)) {
portSel = i;
} else {
portSel = portSel < 0 ? 0 : portSel;
}
i++;
}
} catch (IOException e) {
Activator.log(e);
}
if (portSel >= 0) {
portSelector.select(portSel);
} else {
setMessage(Messages.ArduinoTargetPropertyPage_1, ERROR);
setValid(false);
}
Label boardLabel = new Label(comp, SWT.NONE);
boardLabel.setText(Messages.ArduinoTargetPropertyPage_2);
@ -83,9 +71,9 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
try {
ArduinoBoard currentBoard = arduinoRemote.getBoard();
Collection<ArduinoBoard> boardList = ArduinoManager.instance.getBoards();
Collection<ArduinoBoard> boardList = Activator.getService(ArduinoManager.class).getInstalledBoards();
boards = new ArduinoBoard[boardList.size()];
i = 0;
int i = 0;
int boardSel = 0;
for (ArduinoBoard board : boardList) {
boards[i] = board;
@ -105,7 +93,7 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
@Override
public boolean performOk() {
IRemoteConnection remoteConnection = (IRemoteConnection) getElement().getAdapter(IRemoteConnection.class);
IRemoteConnection remoteConnection = getElement().getAdapter(IRemoteConnection.class);
IRemoteConnectionWorkingCopy workingCopy = remoteConnection.getWorkingCopy();
String portName = portSelector.getItem(portSelector.getSelectionIndex());

View file

@ -0,0 +1,216 @@
/*******************************************************************************
* Copyright (c) 2015 QNX Software Systems 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
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.remote;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map.Entry;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.cdt.serial.SerialPort;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Label;
public class BoardPropertyControl extends Composite {
private Combo portCombo;
private String[] portNames;
private String portName;
private Combo boardCombo;
private ArduinoBoard[] boards;
private ArduinoBoard board;
private List<SelectionListener> listeners = Collections.synchronizedList(new ArrayList<SelectionListener>());
private List<Control> menuControls = new ArrayList<>();
public BoardPropertyControl(Composite parent, int style) {
super(parent, style);
setLayout(new GridLayout(2, false));
Label portLabel = new Label(this, SWT.NONE);
portLabel.setText(Messages.NewArduinoTargetWizardPage_4);
portCombo = new Combo(this, SWT.NONE);
portCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try {
portNames = SerialPort.list();
} catch (IOException e) {
portNames = new String[0];
Activator.log(e);
}
for (String portName : portNames) {
portCombo.add(portName);
}
if (portNames.length > 0) {
portCombo.select(0);
portName = portNames[0];
} else {
portName = ""; //$NON-NLS-1$
}
portCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
portName = portCombo.getText();
fireSelection();
}
});
Label boardLabel = new Label(this, SWT.NONE);
boardLabel.setText(Messages.ArduinoTargetPropertyPage_2);
boardCombo = new Combo(this, SWT.READ_ONLY);
boardCombo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
try {
List<ArduinoBoard> boardList = Activator.getService(ArduinoManager.class).getInstalledBoards();
Collections.sort(boardList, new Comparator<ArduinoBoard>() {
@Override
public int compare(ArduinoBoard o1, ArduinoBoard o2) {
return o1.getName().compareTo(o2.getName());
}
});
boards = boardList.toArray(new ArduinoBoard[boardList.size()]);
for (ArduinoBoard board : boards) {
boardCombo.add(board.getName());
}
boardCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boardChanged();
fireSelection();
}
});
if (boards.length > 0) {
// TODO use preference to remember the last selected board
boardCombo.select(0);
board = boards[0];
updateBoardMenu();
}
} catch (CoreException e) {
Activator.log(e);
}
}
public String getPortName() {
return portName;
}
public ArduinoBoard getSelectedBoard() {
return board;
}
public void addSelectionListener(SelectionListener listener) {
listeners.add(listener);
}
private void updateBoardMenu() {
HierarchicalProperties menus = board.getMenus();
if (menus != null) {
for (Entry<String, HierarchicalProperties> menuEntry : menus.getChildren().entrySet()) {
Label label = new Label(this, SWT.NONE);
label.setText(board.getPlatform().getMenuText(menuEntry.getKey()) + ':');
label.setData(menuEntry.getKey());
menuControls.add(label);
Combo combo = new Combo(this, SWT.READ_ONLY);
combo.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
menuControls.add(combo);
List<String> ids = new ArrayList<>();
for (Entry<String, HierarchicalProperties> valueEntry : menuEntry.getValue().getChildren().entrySet()) {
String value = valueEntry.getValue().getValue();
if (value != null) {
combo.add(value);
ids.add(valueEntry.getKey());
}
}
combo.setData(ids);
combo.select(0);
}
}
}
private void boardChanged() {
int index = boardCombo.getSelectionIndex();
ArduinoBoard newBoard = index < 0 ? null : boards[index];
if (newBoard != board) {
// Clear out old menus
for (Control control : menuControls) {
control.dispose();
}
menuControls.clear();
board = newBoard;
updateBoardMenu();
layout();
getShell().pack();
redraw();
}
}
private void fireSelection() {
for (SelectionListener listener : listeners) {
Event event = new Event();
event.widget = this;
listener.widgetSelected(new SelectionEvent(event));
}
}
public void apply(IRemoteConnectionWorkingCopy workingCopy) {
workingCopy.setAttribute(ArduinoRemoteConnection.PORT_NAME, portName);
workingCopy.setAttribute(ArduinoRemoteConnection.BOARD_NAME, board.getName());
ArduinoPlatform platform = board.getPlatform();
workingCopy.setAttribute(ArduinoRemoteConnection.PLATFORM_NAME, platform.getName());
ArduinoPackage pkg = platform.getPackage();
workingCopy.setAttribute(ArduinoRemoteConnection.PACKAGE_NAME, pkg.getName());
String key = null;
for (Control control : menuControls) {
if (control instanceof Label) {
key = (String) control.getData();
} else if (control instanceof Combo) {
Combo combo = (Combo) control;
@SuppressWarnings("unchecked")
String value = ((List<String>) combo.getData()).get(combo.getSelectionIndex());
if (key != null) {
workingCopy.setAttribute(ArduinoBoard.MENU_QUALIFIER + key, value);
}
}
}
}
}

View file

@ -9,9 +9,6 @@ package org.eclipse.cdt.arduino.ui.internal.remote;
import java.util.Set;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.jface.wizard.Wizard;
@ -38,15 +35,7 @@ public class NewArduinoTargetWizard extends Wizard implements IRemoteUIConnectio
return false;
}
workingCopy.setAttribute(ArduinoRemoteConnection.PORT_NAME, page.portName);
ArduinoBoard board = page.board;
workingCopy.setAttribute(ArduinoRemoteConnection.BOARD_NAME, board.getName());
ArduinoPlatform platform = board.getPlatform();
workingCopy.setAttribute(ArduinoRemoteConnection.PLATFORM_NAME, platform.getName());
ArduinoPackage pkg = platform.getPackage();
workingCopy.setAttribute(ArduinoRemoteConnection.PACKAGE_NAME, pkg.getName());
page.performFinish(workingCopy);
return true;
}

View file

@ -7,18 +7,9 @@
*******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.remote;
import java.io.IOException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoManager;
import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.cdt.serial.SerialPort;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.remote.core.IRemoteConnectionWorkingCopy;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
@ -26,7 +17,6 @@ import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Text;
@ -36,13 +26,7 @@ public class NewArduinoTargetWizardPage extends WizardPage {
String name;
private Text nameText;
String portName;
private String[] portNames;
private Combo portCombo;
ArduinoBoard board;
private ArduinoBoard[] boards;
private Combo boardCombo;
BoardPropertyControl boardControl;
public NewArduinoTargetWizardPage() {
super("NewArduinoTargetPage"); //$NON-NLS-1$
@ -53,17 +37,22 @@ public class NewArduinoTargetWizardPage extends WizardPage {
@Override
public void createControl(Composite parent) {
Composite comp = new Composite(parent, SWT.NONE);
comp.setLayout(new GridLayout(2, false));
comp.setLayout(new GridLayout());
Label nameLabel = new Label(comp, SWT.NONE);
Composite nameComp = new Composite(comp, SWT.NONE);
nameComp.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
nameComp.setLayout(new GridLayout(2, false));
Label nameLabel = new Label(nameComp, SWT.NONE);
nameLabel.setText(Messages.NewArduinoTargetWizardPage_2);
nameText = new Text(comp, SWT.BORDER | SWT.SINGLE);
nameText = new Text(nameComp, SWT.BORDER | SWT.SINGLE);
nameText.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
nameText.setText(Messages.NewArduinoTargetWizardPage_3);
nameText.addKeyListener(new KeyListener() {
@Override
public void keyReleased(KeyEvent e) {
name = nameText.getText();
updateStatus();
}
@ -72,51 +61,9 @@ public class NewArduinoTargetWizardPage extends WizardPage {
}
});
Label portLabel = new Label(comp, SWT.NONE);
portLabel.setText(Messages.NewArduinoTargetWizardPage_4);
portCombo = new Combo(comp, SWT.READ_ONLY);
portCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try {
portNames = SerialPort.list();
} catch (IOException e) {
portNames = new String[0];
Activator.log(e);
}
for (String portName : portNames) {
portCombo.add(portName);
}
portCombo.select(0);
portCombo.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateStatus();
}
});
Label boardLabel = new Label(comp, SWT.NONE);
boardLabel.setText(Messages.NewArduinoTargetWizardPage_5);
boardCombo = new Combo(comp, SWT.READ_ONLY);
boardCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try {
List<ArduinoBoard> boardList = ArduinoManager.instance.getInstalledBoards();
Collections.sort(boardList, new Comparator<ArduinoBoard>() {
@Override
public int compare(ArduinoBoard o1, ArduinoBoard o2) {
return o1.getName().compareTo(o2.getName());
}
});
boards = boardList.toArray(new ArduinoBoard[0]);
for (ArduinoBoard board : boards) {
boardCombo.add(board.getName());
}
boardCombo.select(0);
} catch (CoreException e) {
Activator.log(e);
}
boardCombo.addSelectionListener(new SelectionAdapter() {
boardControl = new BoardPropertyControl(comp, SWT.NONE);
boardControl.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
boardControl.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
updateStatus();
@ -128,15 +75,12 @@ public class NewArduinoTargetWizardPage extends WizardPage {
}
private void updateStatus() {
name = nameText.getText();
setPageComplete(name != null && !name.isEmpty() && boardControl.getPortName() != null
&& boardControl.getSelectedBoard() != null);
}
int portIndex = portCombo.getSelectionIndex();
portName = portIndex < 0 ? null : portNames[portIndex];
int boardIndex = boardCombo.getSelectionIndex();
board = boardIndex < 0 ? null : boards[boardIndex];
setPageComplete(!name.isEmpty() && portName != null && board != null);
public void performFinish(IRemoteConnectionWorkingCopy workingCopy) {
boardControl.apply(workingCopy);
}
}