diff options
author | Doug Schaefer | 2016-04-27 20:44:47 +0000 |
---|---|---|
committer | Doug Schaefer | 2016-04-28 15:14:07 +0000 |
commit | 7139dc2f1e35fc44b92c8e1baf06933624992731 (patch) | |
tree | b773cb3411d11ad1ddae168c23415b195e131015 /toolchains/arduino | |
parent | b2300cbcfe632078ad6b8c4b4b934106e7abbf97 (diff) | |
download | org.eclipse.cdt-7139dc2f1e35fc44b92c8e1baf06933624992731.tar.gz org.eclipse.cdt-7139dc2f1e35fc44b92c8e1baf06933624992731.tar.xz org.eclipse.cdt-7139dc2f1e35fc44b92c8e1baf06933624992731.zip |
Modernize Arduino plug-ins. Adjust APIs to suite.
Change-Id: Ic877c8f0992874e647d4b464502165d7bd3ebe0e
Diffstat (limited to 'toolchains/arduino')
28 files changed, 691 insertions, 1187 deletions
diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF b/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF index 7a81a68875e..2f617f1dded 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/META-INF/MANIFEST.MF @@ -15,14 +15,14 @@ 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.freemarker;bundle-version="2.3.22", - org.eclipse.launchbar.remote.core;bundle-version="1.0.0" + org.eclipse.launchbar.remote.core;bundle-version="1.0.0", + org.eclipse.tools.templates.freemarker;bundle-version="1.0.0";visibility:=reexport, + org.eclipse.cdt.build.gcc.core;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Bundle-ActivationPolicy: lazy 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 diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml index 8399a090f76..8ececf48b6a 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/plugin.xml @@ -75,45 +75,29 @@ </run> </runtime> <builder - id="org.eclipse.cdt.arduino.core.arduinoBuilder"> + id="com.qnx.tools.ide.qde.core.cbuilder"> </builder> </extension> <extension - id="arduinoBuilder" - name="%ArduinoBuilder.name" - point="org.eclipse.core.resources.builders"> - <builder - callOnEmptyDelta="true" - hasNature="true" - isConfigurable="true" - supportsConfigurations="true"> - <run - class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder"> - </run> - </builder> + 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> <extension - point="org.eclipse.cdt.core.ScannerInfoProvider2"> + point="org.eclipse.cdt.core.buildConfigProvider"> <provider - builder="org.eclipse.cdt.arduino.core.arduinoBuilder" - class="org.eclipse.cdt.arduino.core.internal.ArduinoScannerInfoProvider"> + class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfigurationProvider" + id="org.eclipse.cdt.arduino.core.provider" + natureId="org.eclipse.cdt.arduino.core.arduinoNature"> </provider> </extension> <extension - point="org.eclipse.core.runtime.adapters"> - <factory - adaptableType="org.eclipse.core.resources.IBuildConfiguration" - class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration$Factory"> - <adapter - type="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration"> - </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> + point="org.eclipse.cdt.core.toolChainProvider"> + <provider + class="org.eclipse.cdt.arduino.core.internal.build.ArduinoToolChainProvider" + id="org.eclipse.cdt.arduino.core.toolChainProvider"> + </provider> </extension> </plugin> diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java index 342e8b451cc..e34ed5e625d 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/Activator.java @@ -11,12 +11,8 @@ package org.eclipse.cdt.arduino.core.internal; 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.osgi.framework.BundleContext; @@ -46,11 +42,13 @@ public class Activator extends Plugin { } } + @Override public void start(BundleContext bundleContext) throws Exception { plugin = this; bundleContext.registerService(ArduinoManager.class, new ArduinoManager(), null); } + @Override public void stop(BundleContext bundleContext) throws Exception { plugin = null; } @@ -61,10 +59,4 @@ 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$ - } - } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java index b54bf1c024a..a5f2218d3ea 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoProjectGenerator.java @@ -1,73 +1,54 @@ /******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. + * Copyright (c) 2015, 2016 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; -import java.util.HashMap; import java.util.Map; -import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder; import org.eclipse.cdt.core.CCProjectNature; import org.eclipse.cdt.core.CProjectNature; +import org.eclipse.cdt.core.build.CBuilder; 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.IProject; import org.eclipse.core.resources.IProjectDescription; -import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; +import org.eclipse.tools.templates.freemarker.FMProjectGenerator; +import org.osgi.framework.Bundle; -public class ArduinoProjectGenerator { +public class ArduinoProjectGenerator extends FMProjectGenerator { - private final IProject project; - private IFile sourceFile; - - public ArduinoProjectGenerator(IProject project) { - this.project = project; + public ArduinoProjectGenerator(String manifestFile) { + super(manifestFile); } - - 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(); - String[] newIds = new String[oldIds.length + 3]; - System.arraycopy(oldIds, 0, newIds, 0, oldIds.length); - newIds[newIds.length - 3] = CProjectNature.C_NATURE_ID; - newIds[newIds.length - 2] = CCProjectNature.CC_NATURE_ID; - newIds[newIds.length - 1] = ArduinoProjectNature.ID; - projDesc.setNatureIds(newIds); - - // Add Arduino Builder - ICommand command = projDesc.newCommand(); - command.setBuilderName(ArduinoBuilder.ID); - command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false); - projDesc.setBuildSpec(new ICommand[] { command }); - - project.setDescription(projDesc, monitor); - - IPathEntry[] entries = new IPathEntry[] { CoreModel.newSourceEntry(project.getFullPath()) }; - CoreModel.getDefault().create(project).setRawPathEntries(entries, monitor); + + @Override + protected void initProjectDescription(IProjectDescription description) { + description + .setNatureIds(new String[] { CProjectNature.C_NATURE_ID, CCProjectNature.CC_NATURE_ID, ArduinoProjectNature.ID }); + ICommand command = description.newCommand(); + CBuilder.setupBuilder(command); + description.setBuildSpec(new ICommand[] { command }); } - public IFile getSourceFile() { - return sourceFile; + @Override + public Bundle getSourceBundle() { + return Activator.getPlugin().getBundle(); + } + + @Override + public void generate(Map<String, Object> model, IProgressMonitor monitor) throws CoreException { + super.generate(model, monitor); + IProject project = getProject(); + CoreModel.getDefault().create(project).setRawPathEntries(new IPathEntry[] { + CoreModel.newSourceEntry(project.getFullPath()) + }, monitor); } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java deleted file mode 100644 index 648a20c77d0..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoScannerInfoProvider.java +++ /dev/null @@ -1,45 +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; - -import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; -import org.eclipse.cdt.core.parser.IScannerInfo; -import org.eclipse.cdt.core.parser.IScannerInfoChangeListener; -import org.eclipse.cdt.core.parser.IScannerInfoProvider; -import org.eclipse.core.resources.IBuildConfiguration; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.runtime.CoreException; - -/** - * Responsible for collecting scanner info on Arduino Projects. - */ -public class ArduinoScannerInfoProvider implements IScannerInfoProvider { - - @Override - public IScannerInfo getScannerInformation(IResource resource) { - try { - IProject project = resource.getProject(); - IBuildConfiguration config = project.getActiveBuildConfig(); - ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class); - return arduinoConfig.getScannerInfo(resource); - } catch (CoreException e) { - Activator.log(e); - return null; - } - } - - @Override - public void subscribe(IResource resource, IScannerInfoChangeListener listener) { - } - - @Override - public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) { - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoTemplateGenerator.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoTemplateGenerator.java deleted file mode 100644 index 3725e794f67..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/ArduinoTemplateGenerator.java +++ /dev/null @@ -1,95 +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; - -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; -import java.nio.charset.StandardCharsets; - -import org.eclipse.core.resources.IFile; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.FileLocator; -import org.eclipse.core.runtime.IProgressMonitor; -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 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); - config.setTemplateLoader(this); - } - - public void generateFile(final Object model, String templateFile, final IFile outputFile, IProgressMonitor monitor) - throws CoreException { - try { - final Template template = config.getTemplate(templateFile); - try (StringWriter writer = new StringWriter()) { - template.process(model, writer); - try (ByteArrayInputStream in = new ByteArrayInputStream( - writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8))) { - if (outputFile.exists()) { - outputFile.setContents(in, true, true, monitor); - } else { - outputFile.create(in, true, monitor); - } - } - } - } catch (IOException | TemplateException e) { - throw new CoreException( - 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 - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java index 5fe77c47982..64eb2b07231 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/board/ArduinoManager.java @@ -45,7 +45,7 @@ import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.Messages; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration; -import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.cdt.core.build.ICBuildConfiguration; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.ProjectScope; import org.eclipse.core.runtime.CoreException; @@ -76,6 +76,7 @@ public class ArduinoManager { public void loadIndices() { new Job(Messages.ArduinoBoardManager_0) { + @Override protected IStatus run(IProgressMonitor monitor) { synchronized (ArduinoManager.this) { String[] boardUrls = ArduinoPreferences.getBoardUrls().split("\n"); //$NON-NLS-1$ @@ -207,7 +208,7 @@ public class ArduinoManager { private static final String LIBRARIES = "libraries"; //$NON-NLS-1$ private IEclipsePreferences getSettings(IProject project) { - return (IEclipsePreferences) new ProjectScope(project).getNode(Activator.getId()); + return new ProjectScope(project).getNode(Activator.getId()); } public Collection<ArduinoLibrary> getLibraries(IProject project) throws CoreException { @@ -218,8 +219,8 @@ public class ArduinoManager { Set<String> libraryNames = new Gson().fromJson(librarySetting, stringSet); LibraryIndex index = Activator.getService(ArduinoManager.class).getLibraryIndex(); - ArduinoPlatform platform = project.getActiveBuildConfig().getAdapter(ArduinoBuildConfiguration.class).getBoard() - .getPlatform(); + ICBuildConfiguration cconfig = project.getActiveBuildConfig().getAdapter(ICBuildConfiguration.class); + ArduinoPlatform platform = cconfig.getAdapter(ArduinoBuildConfiguration.class).getBoard().getPlatform(); List<ArduinoLibrary> libraries = new ArrayList<>(libraryNames.size()); for (String name : libraryNames) { ArduinoLibrary lib = index.getLibrary(name); @@ -247,6 +248,7 @@ public class ArduinoManager { } new Job(Messages.ArduinoManager_0) { + @Override protected IStatus run(IProgressMonitor monitor) { MultiStatus mstatus = new MultiStatus(Activator.getId(), 0, Messages.ArduinoManager_1, null); for (ArduinoLibrary library : libraries) { @@ -255,16 +257,6 @@ public class ArduinoManager { mstatus.add(status); } } - - // Clear the scanner info caches to pick up new includes - try { - for (IBuildConfiguration config : project.getBuildConfigs()) { - ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class); - arduinoConfig.clearScannerInfoCache(); - } - } catch (CoreException e) { - mstatus.add(e.getStatus()); - } return mstatus; } }.schedule(); diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java index 0fb96aa25a9..c0ee4bcb215 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfiguration.java @@ -8,25 +8,30 @@ package org.eclipse.cdt.arduino.core.internal.build; import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.IOException; import java.io.InputStreamReader; -import java.nio.file.Files; +import java.io.Reader; +import java.io.StringWriter; +import java.net.URISyntaxException; +import java.net.URL; +import java.nio.charset.StandardCharsets; 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; 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 java.util.stream.Collectors; 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; @@ -34,152 +39,107 @@ 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.ToolDependency; -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.ConsoleOutputStream; +import org.eclipse.cdt.core.ErrorParserManager; +import org.eclipse.cdt.core.IConsoleParser; +import org.eclipse.cdt.core.build.CBuildConfiguration; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChainManager; +import org.eclipse.cdt.core.build.IToolChainProvider; +import org.eclipse.cdt.core.model.ICModelMarker; import org.eclipse.cdt.core.model.ISourceRoot; import org.eclipse.cdt.core.parser.ExtendedScannerInfo; import org.eclipse.cdt.core.parser.IScannerInfo; +import org.eclipse.cdt.core.resources.IConsole; import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IContainer; 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.FileLocator; 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 { +import freemarker.cache.TemplateLoader; +import freemarker.template.Configuration; +import freemarker.template.Template; +import freemarker.template.TemplateException; + +public class ArduinoBuildConfiguration extends CBuildConfiguration implements TemplateLoader { 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 final ArduinoBoard board; + private final String launchMode; private Properties properties; - // Cache for scanner info - private IScannerInfo cScannerInfo; - private IScannerInfo cppScannerInfo; + // for Makefile generation + private Configuration templateConfig; private final static boolean isWindows = Platform.getOS().equals(Platform.OS_WIN32); - private ArduinoBuildConfiguration(IBuildConfiguration config) { - this.config = config; - } - - private static Map<IBuildConfiguration, ArduinoBuildConfiguration> cache = new HashMap<>(); - - public static class Factory implements IAdapterFactory { - @SuppressWarnings("unchecked") - @Override - public <T> T getAdapter(Object adaptableObject, Class<T> adapterType) { - if (adapterType.equals(ArduinoBuildConfiguration.class) && adaptableObject instanceof IBuildConfiguration) { - IBuildConfiguration config = (IBuildConfiguration) adaptableObject; - ArduinoBuildConfiguration arduinoConfig = cache.get(config); - if (arduinoConfig == null) { - arduinoConfig = new ArduinoBuildConfiguration(config); - cache.put(config, arduinoConfig); + public ArduinoBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { + super(config, name); + + Preferences 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$ + ArduinoBoard b = manager.getBoard(boardName, platformName, packageName); + + if (b == null) { + // Default to Uno or first one we find + b = manager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (b == null) { + List<ArduinoBoard> boards = manager.getInstalledBoards(); + if (!boards.isEmpty()) { + b = boards.get(0); } - return (T) arduinoConfig; } - return null; - } - - @Override - public Class<?>[] getAdapterList() { - return new Class<?>[] { ArduinoBuildConfiguration.class }; - } - } - - 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()) { - if (!config.getName().equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { - ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class); - if (arduinoConfig.matches(target)) { - return arduinoConfig; - } - } - } - - // Not found, need to create one - Set<String> configNames = new HashSet<>(); - for (IBuildConfiguration config : project.getBuildConfigs()) { - configNames.add(config.getName()); - } - String newName = board.getId(); - int n = 0; - while (configNames.contains(newName)) { - newName = board.getId() + (++n); - } - configNames.add(newName); - IProjectDescription projectDesc = project.getDescription(); - projectDesc.setBuildConfigs(configNames.toArray(new String[configNames.size()])); - project.setDescription(projectDesc, monitor); - - // set it up for the board - IBuildConfiguration config = project.getBuildConfig(newName); - ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class); - arduinoConfig.setBoard(target); - - return arduinoConfig; - } - - public void setActive(IProgressMonitor monitor) throws CoreException { - IProject project = config.getProject(); - if (config.equals(project.getActiveBuildConfig())) { - // already set - return; } + board = b; - 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)); + int i = name.lastIndexOf('.'); + this.launchMode = name.substring(i + 1); } - 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 { + ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoBoard board, String launchMode) + throws CoreException { + super(config, name); this.board = board; + this.launchMode = launchMode; + + // Create the toolChain + IToolChainManager toolChainManager = Activator.getService(IToolChainManager.class); + IToolChainProvider provider = toolChainManager.getProvider(ArduinoToolChainProvider.ID); + IToolChain toolChain = new ArduinoToolChain(provider, this); + toolChainManager.addToolChain(toolChain); + setToolChain(toolChain); + // Store the board identifer ArduinoPlatform platform = board.getPlatform(); ArduinoPackage pkg = platform.getPackage(); - IEclipsePreferences settings = getSettings(); + Preferences settings = getSettings(); settings.put(PACKAGE_NAME, pkg.getName()); settings.put(PLATFORM_NAME, platform.getName()); settings.put(BOARD_NAME, board.getName()); + try { settings.flush(); } catch (BackingStoreException e) { @@ -187,19 +147,14 @@ public class ArduinoBuildConfiguration { } } - 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()); + ArduinoBuildConfiguration(IBuildConfiguration config, String name, ArduinoRemoteConnection target, + String launchMode) throws CoreException { + this(config, name, target.getBoard(), launchMode); + // Store the menu settings HierarchicalProperties menus = board.getMenus(); if (menus != null) { + Preferences settings = getSettings(); for (String id : menus.getChildren().keySet()) { String key = ArduinoBoard.MENU_QUALIFIER + id; String value = target.getRemoteConnection().getAttribute(key); @@ -207,13 +162,30 @@ public class ArduinoBuildConfiguration { 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$ + } } + } - try { - settings.flush(); - } catch (BackingStoreException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e)); //$NON-NLS-1$ + static String generateName(ArduinoBoard board, String launchMode) { + return "arduino." + board.getId() + '.' + launchMode; //$NON-NLS-1$ + } + + @SuppressWarnings("unchecked") + @Override + public <T> T getAdapter(Class<T> adapter) { + if (adapter.equals(ArduinoBuildConfiguration.class)) { + return (T) this; } + return super.getAdapter(adapter); + } + + public String getLaunchMode() { + return launchMode; } public boolean matches(ArduinoRemoteConnection target) throws CoreException { @@ -222,7 +194,7 @@ public class ArduinoBuildConfiguration { return false; } - IEclipsePreferences settings = getSettings(); + Preferences settings = getSettings(); HierarchicalProperties menus = board.getMenus(); if (menus != null) { for (String id : menus.getChildren().keySet()) { @@ -237,24 +209,6 @@ public class ArduinoBuildConfiguration { } public ArduinoBoard getBoard() throws CoreException { - if (board == null) { - 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 = 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; } @@ -268,7 +222,7 @@ public class ArduinoBuildConfiguration { 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(); + String configName = getBuildConfiguration().getName(); if (configName.equals(IBuildConfiguration.DEFAULT_CONFIG_NAME)) { configName = "default"; //$NON-NLS-1$ } @@ -289,7 +243,7 @@ public class ArduinoBuildConfiguration { properties.putAll(board.getBoardProperties()); // Menus - IEclipsePreferences settings = getSettings(); + Preferences settings = getSettings(); HierarchicalProperties menus = board.getMenus(); if (menus != null) { for (String menuId : menus.getChildren().keySet()) { @@ -302,48 +256,22 @@ public class ArduinoBuildConfiguration { } // always do this in case the project changes names - properties.put("build.project_name", config.getProject().getName()); //$NON-NLS-1$ + properties.put("build.project_name", getProject().getName()); //$NON-NLS-1$ return properties; } - public IFolder getBuildFolder() throws CoreException { - IProject project = config.getProject(); - return project.getFolder("build"); //$NON-NLS-1$ - } - - public File getBuildDirectory() throws CoreException { - return new File(getBuildFolder().getLocationURI()); - } - public IFile getMakeFile() throws CoreException { - IFolder buildFolder = getBuildFolder(); + IFolder buildFolder = (IFolder) getBuildContainer(); ArduinoBoard board = getBoard(); String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$ return buildFolder.getFile(makeFileName); } - public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException { - 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(); - IPathEntry[] newEntries = new IPathEntry[oldEntries.length + 1]; - System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length); - newEntries[oldEntries.length] = output; - cproject.setRawPathEntries(newEntries, monitor); - } - + public Map<String, Object> getBuildModel() throws CoreException { + IProject project = getProject(); ArduinoBoard board = getBoard(); ArduinoPlatform platform = board.getPlatform(); - IFile makeFile = getMakeFile(); - - // The board id Map<String, Object> buildModel = new HashMap<>(); buildModel.put("boardId", board.getId()); //$NON-NLS-1$ @@ -417,9 +345,56 @@ public class ArduinoBuildConfiguration { 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(); - templateGen.generateFile(buildModel, "board.mk", makeFile, monitor); //$NON-NLS-1$ - return makeFile; + return buildModel; + } + + public IFile generateMakeFile(IProgressMonitor monitor) throws CoreException { + IFolder buildFolder = (IFolder) getBuildContainer(); + if (!buildFolder.exists()) { + buildFolder.create(true, true, monitor); + } + + IFile makefile = getMakeFile(); + + Map<String, Object> buildModel = getBuildModel(); + + // Generate the Makefile + try (StringWriter writer = new StringWriter()) { + if (templateConfig == null) { + templateConfig = new Configuration(Configuration.VERSION_2_3_22); + templateConfig.setTemplateLoader(this); + } + + Template template = templateConfig.getTemplate("templates/Makefile"); //$NON-NLS-1$ + template.process(buildModel, writer); + try (ByteArrayInputStream in = new ByteArrayInputStream( + writer.getBuffer().toString().getBytes(StandardCharsets.UTF_8))) { + createParent(makefile, monitor); + if (makefile.exists()) { + makefile.setContents(in, true, true, monitor); + } else { + makefile.create(in, true, monitor); + } + } + } catch (IOException | TemplateException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Error generating makefile", e)); + } + + return makefile; + } + + protected static void createParent(IResource child, IProgressMonitor monitor) throws CoreException { + if (child == null) + return; + + IContainer container = child.getParent(); + if (container.exists()) { + return; + } + + IFolder parent = container.getAdapter(IFolder.class); + createParent(parent, monitor); + parent.create(true, true, monitor); } public static boolean isSource(String filename) { @@ -435,35 +410,30 @@ public class ArduinoBuildConfiguration { } } - private String resolveProperty(String property, Properties dict) { - String res = dict.getProperty(property); - if (res == null) { - return null; - } - + private String resolvePropertyValue(String value, Properties dict) { String last; do { - last = res; - for (int i = res.indexOf('{'); i >= 0; i = res.indexOf('{', i)) { + last = value; + for (int i = value.indexOf('{'); i >= 0; i = value.indexOf('{', i)) { i++; - int n = res.indexOf('}', i); + int n = value.indexOf('}', i); if (n >= 0) { - String p2 = res.substring(i, n); + String p2 = value.substring(i, n); String r2 = dict.getProperty(p2); if (r2 != null) { - res = res.replace('{' + p2 + '}', r2); + value = value.replace('{' + p2 + '}', r2); } } i = n; } - } while (!res.equals(last)); + } while (!value.equals(last)); - return res; + return value; } - public void setEnvironment(Map<String, String> env) throws CoreException { - // Everything is specified with full path, do not need to add anything - // to the environment. + private String resolveProperty(String property, Properties dict) { + String value = dict.getProperty(property); + return value != null ? resolvePropertyValue(value, dict) : null; } public String getMakeCommand() { @@ -546,31 +516,75 @@ public class ArduinoBuildConfiguration { } } - 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: - if (cppScannerInfo == null) { - cppScannerInfo = calculateScannerInfo("recipe.cpp.o.pattern", resource); //$NON-NLS-1$ + // Scanner Info Cache + private String[] cachedIncludePath; + private String cachedInfoCommand; + private IScannerInfo cachedScannerInfo; + + @Override + public IScannerInfo getScannerInformation(IResource resource) { + try { + IContentType contentType = CCorePlugin.getContentType(resource.getProject(), resource.getName()); + String recipe; + if (contentType != null && (contentType.getId() == CCorePlugin.CONTENT_TYPE_CSOURCE + || contentType.getId() == CCorePlugin.CONTENT_TYPE_CSOURCE)) { + recipe = "recipe.c.o.pattern"; //$NON-NLS-1$ + } else { + recipe = "recipe.cpp.o.pattern"; //$NON-NLS-1$ + } + + ArduinoPlatform platform = getBoard().getPlatform(); + Properties properties = new Properties(); + properties.putAll(getProperties()); + + // Overrides for scanner discovery + properties.put("source_file", ""); //$NON-NLS-1$ //$NON-NLS-2$ + properties.put("object_file", "-"); //$NON-NLS-1$ //$NON-NLS-2$ + // the base scanner info does includes + properties.put("includes", ""); //$NON-NLS-1$ //$NON-NLS-2$ + String commandString = resolveProperty(recipe, properties); + + List<Path> includePath = new ArrayList<>(); + includePath.addAll(platform.getIncludePath()); + Collection<ArduinoLibrary> libs = manager.getLibraries(getProject()); + for (ArduinoLibrary lib : libs) { + includePath.addAll(lib.getIncludePath()); + } + String[] includes = includePath.stream() + .map(path -> resolvePropertyValue(path.toString(), properties)).collect(Collectors.toList()) + .toArray(new String[includePath.size()]); + + // Use cache if we can + if (cachedScannerInfo != null && cachedInfoCommand.equals(commandString) + && cachedIncludePath.length == includes.length) { + boolean matches = true; + for (int i = 0; i < includes.length; ++i) { + if (!includes[i].equals(cachedIncludePath[i])) { + matches = false; + break; + } } - return cppScannerInfo; - default: - if (cScannerInfo == null) { - cScannerInfo = calculateScannerInfo("recipe.c.o.pattern", resource); //$NON-NLS-1$ + + if (matches) { + return cachedScannerInfo; } - return cScannerInfo; } - } - // use the cpp scanner info if all else fails - return cppScannerInfo; - } - public void clearScannerInfoCache() { - cppScannerInfo = null; - cScannerInfo = null; + ExtendedScannerInfo baseInfo = new ExtendedScannerInfo(null, includes); + String[] command = splitCommand(commandString); + IScannerInfo info = getToolChain().getScannerInfo(getBuildConfiguration(), Paths.get(command[0]), + Arrays.copyOfRange(command, 1, command.length), baseInfo, resource, getBuildDirectoryURI()); + + // cache the results + cachedScannerInfo = info; + cachedInfoCommand = commandString; + cachedIncludePath = includes; + + return info; + } catch (CoreException e) { + Activator.log(e); + return null; + } } public static String pathString(Path path) { @@ -581,109 +595,151 @@ public class ArduinoBuildConfiguration { return str; } - private IScannerInfo calculateScannerInfo(String recipe, IResource resource) throws CoreException { + 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$ + } + + @Override + public IProject[] build(int kind, Map<String, String> args, IConsole console, IProgressMonitor monitor) + throws CoreException { + IProject project = getProject(); try { - ArduinoPlatform platform = getBoard().getPlatform(); - Properties properties = new Properties(); - properties.putAll(getProperties()); + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - 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$ + ConsoleOutputStream consoleOut = console.getOutputStream(); + consoleOut.write(String.format("\nBuilding %s\n", project.getName())); - 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$ + generateMakeFile(monitor); + + try (ErrorParserManager epm = new ErrorParserManager(project, getBuildDirectoryURI(), this, + getToolChain().getErrorParserIds())) { + ProcessBuilder processBuilder = new ProcessBuilder().command(getBuildCommand()) + .directory(getBuildDirectory().toFile()); + setBuildEnvironment(processBuilder.environment()); + Process process = processBuilder.start(); + if (watchProcess(process, new IConsoleParser[] { epm }, console) == 0) { + showSizes(console); } } - 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()); + getBuildContainer().refreshLocal(IResource.DEPTH_INFINITE, monitor); + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); + } + + // TODO if there are references we want to watch, return them here + return new IProject[] { project }; + } + + @Override + public void clean(IConsole console, IProgressMonitor monitor) throws CoreException { + try { + IProject project = getProject(); + project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); + + ConsoleOutputStream consoleOut = console.getOutputStream(); + consoleOut.write(String.format("\nCleaning %s\n", project.getName())); + + ProcessBuilder processBuilder = new ProcessBuilder().command(getCleanCommand()) + .directory(getBuildDirectory().toFile()); + setBuildEnvironment(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; + watchProcess(process, new IConsoleParser[0], console); + + getBuildContainer().refreshLocal(IResource.DEPTH_INFINITE, monitor); } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Compiler built-ins", e)); //$NON-NLS-1$ + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); } } - 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$ - } + private void showSizes(IConsole console) throws CoreException { + try { + int codeSize = -1; + int dataSize = -1; - public ArduinoConsoleParser[] getBuildConsoleParsers() { - // ../src/Test.cpp:4:1: error: 'x' was not declared in this scope + String codeSizeRegex = getCodeSizeRegex(); + Pattern codeSizePattern = codeSizeRegex != null ? Pattern.compile(codeSizeRegex) : null; + String dataSizeRegex = getDataSizeRegex(); + Pattern dataSizePattern = dataSizeRegex != null ? Pattern.compile(dataSizeRegex) : null; - return new ArduinoConsoleParser[] { new ArduinoErrorParser("(.*?):(\\d+):(\\d+:)? (fatal )?error: (.*)") { //$NON-NLS-1$ - @Override - protected int getSeverity(Matcher matcher) { - return IMarker.SEVERITY_ERROR; + if (codeSizePattern == null && dataSizePattern == null) { + return; } - @Override - protected String getMessage(Matcher matcher) { - return matcher.group(matcher.groupCount()); + int maxCodeSize = getMaxCodeSize(); + int maxDataSize = getMaxDataSize(); + + ProcessBuilder processBuilder = new ProcessBuilder().command(getSizeCommand()) + .directory(getBuildDirectory().toFile()).redirectErrorStream(true); + setBuildEnvironment(processBuilder.environment()); + Process process = processBuilder.start(); + try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) { + for (String line = processOut.readLine(); line != null; line = processOut.readLine()) { + if (codeSizePattern != null) { + Matcher matcher = codeSizePattern.matcher(line); + if (matcher.matches()) { + codeSize += Integer.parseInt(matcher.group(1)); + } + } + if (dataSizePattern != null) { + Matcher matcher = dataSizePattern.matcher(line); + if (matcher.matches()) { + dataSize += Integer.parseInt(matcher.group(1)); + } + } + } } - @Override - protected int getLineNumber(Matcher matcher) { - return Integer.parseInt(matcher.group(2)); + ConsoleOutputStream consoleOut = console.getOutputStream(); + consoleOut.write("Program store usage: " + codeSize); + if (maxCodeSize > 0) { + consoleOut.write(" of maximum " + maxCodeSize); } + consoleOut.write(" bytes\n"); - @Override - protected String getFileName(Matcher matcher) { - return matcher.group(1); + if (maxDataSize >= 0) { + consoleOut.write("Initial RAM usage: " + dataSize); + if (maxCodeSize > 0) { + consoleOut.write(" of maximum " + maxDataSize); + } + consoleOut.write(" bytes\n"); } + } catch (IOException e) { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Checking sizes", e)); + } + } + + @Override + public Object findTemplateSource(String name) throws IOException { + return FileLocator.find(Activator.getPlugin().getBundle(), new org.eclipse.core.runtime.Path(name), null); + } - @Override - protected int getLinkOffset(Matcher matcher) { + @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 - protected int getLinkLength(Matcher matcher) { - return matcher.group(1).length() + 1 + matcher.group(2).length() + 1 + matcher.group(3).length(); - } - } }; + @Override + public Reader getReader(Object source, String encoding) throws IOException { + URL url = (URL) source; + return new InputStreamReader(url.openStream(), encoding); + } + + @Override + public void closeTemplateSource(Object arg0) throws IOException { + // Nothing } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java new file mode 100644 index 00000000000..3268020022e --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuildConfigurationProvider.java @@ -0,0 +1,105 @@ +/******************************************************************************* + * Copyright (c) 2016 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.util.List; + +import org.eclipse.cdt.arduino.core.internal.Activator; +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.remote.ArduinoRemoteConnection; +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.ICBuildConfigurationProvider; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IProgressMonitor; + +public class ArduinoBuildConfigurationProvider implements ICBuildConfigurationProvider { + + public static final String ID = "org.eclipse.cdt.arduino.core.provider"; //$NON-NLS-1$ + + private static final ICBuildConfigurationManager configManager = Activator + .getService(ICBuildConfigurationManager.class); + private static final ArduinoManager arduinoManager = Activator.getService(ArduinoManager.class); + + @Override + public String getId() { + return ID; + } + + @Override + public ICBuildConfiguration getCBuildConfiguration(IBuildConfiguration config, String name) throws CoreException { + return new ArduinoBuildConfiguration(config, name); + } + + @Override + public ICBuildConfiguration getDefaultCBuildConfiguration(IProject project) throws CoreException { + ArduinoBoard board = arduinoManager.getBoard("Arduino/Genuino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ + if (board == null) { + List<ArduinoBoard> boards = arduinoManager.getInstalledBoards(); + if (!boards.isEmpty()) { + board = boards.get(0); + } + } + if (board != null) { + String launchMode = "run"; //$NON-NLS-1$ + for (IBuildConfiguration config : project.getBuildConfigs()) { + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + if (cconfig != null) { + ArduinoBuildConfiguration arduinoConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class); + if (arduinoConfig != null && arduinoConfig.getLaunchMode().equals(launchMode) + && arduinoConfig.getBoard().equals(board)) { + return arduinoConfig; + } + } + } + + // not found, create one + String configName = ArduinoBuildConfiguration.generateName(board, launchMode); + IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, + null); + ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, board, + launchMode); + arduinoConfig.setActive(null); + configManager.addBuildConfiguration(config, arduinoConfig); + return arduinoConfig; + } + return null; + } + + public ArduinoBuildConfiguration getConfiguration(IProject project, ArduinoRemoteConnection target, + String launchMode, + IProgressMonitor monitor) throws CoreException { + ArduinoBoard board = target.getBoard(); + for (IBuildConfiguration config : project.getBuildConfigs()) { + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + if (cconfig != null) { + ArduinoBuildConfiguration arduinoConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class); + if (arduinoConfig != null && arduinoConfig.getLaunchMode().equals(launchMode) + && arduinoConfig.getBoard().equals(board) && arduinoConfig.matches(target)) { + return arduinoConfig; + } + } + } + return null; + } + + public ArduinoBuildConfiguration createConfiguration(IProject project, ArduinoRemoteConnection target, + String launchMode, + IProgressMonitor monitor) throws CoreException { + ArduinoBoard board = target.getBoard(); + String configName = ArduinoBuildConfiguration.generateName(board, launchMode); + IBuildConfiguration config = configManager.createBuildConfiguration(this, project, configName, + monitor); + ArduinoBuildConfiguration arduinoConfig = new ArduinoBuildConfiguration(config, configName, target, launchMode); + return arduinoConfig; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java deleted file mode 100644 index 18753269114..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoBuilder.java +++ /dev/null @@ -1,147 +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.build; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.InputStreamReader; -import java.util.Map; -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.console.ArduinoConsoleService; -import org.eclipse.cdt.core.model.ICModelMarker; -import org.eclipse.core.resources.IProject; -import org.eclipse.core.resources.IResource; -import org.eclipse.core.resources.IncrementalProjectBuilder; -import org.eclipse.core.runtime.CoreException; -import org.eclipse.core.runtime.IProgressMonitor; -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. - */ -public class ArduinoBuilder extends IncrementalProjectBuilder { - - public static final String ID = Activator.getId() + ".arduinoBuilder"; //$NON-NLS-1$ - - @Override - protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException { - IProject project = getProject(); - try { - project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - - ArduinoConsoleService consoleService = Activator.getConsoleService(); - consoleService.writeOutput(String.format("\nBuilding %s\n", project.getName())); - - ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class); - config.generateMakeFile(monitor); - - ProcessBuilder processBuilder = new ProcessBuilder().command(config.getBuildCommand()) - .directory(config.getBuildDirectory()); - config.setEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); - - consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder()); - - if (process.exitValue() == 0) { - showSizes(config, consoleService); - } - - config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor); - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); - } - - // TODO if there are references we want to watch, return them here - return new IProject[] { project }; - } - - @Override - protected void clean(IProgressMonitor monitor) throws CoreException { - try { - IProject project = getProject(); - project.deleteMarkers(ICModelMarker.C_MODEL_PROBLEM_MARKER, true, IResource.DEPTH_INFINITE); - - ArduinoConsoleService consoleService = Activator.getConsoleService(); - consoleService.writeOutput(String.format("\nCleaning %s\n", project.getName())); - - ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class); - - ProcessBuilder processBuilder = new ProcessBuilder().command(config.getCleanCommand()) - .directory(config.getBuildDirectory()); - config.setEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); - - consoleService.monitor(process, config.getBuildConsoleParsers(), config.getBuildFolder()); - - config.getBuildFolder().refreshLocal(IResource.DEPTH_INFINITE, monitor); - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e)); - } - } - - private void showSizes(ArduinoBuildConfiguration config, ArduinoConsoleService console) throws CoreException { - try { - int codeSize = -1; - int dataSize = -1; - - String codeSizeRegex = config.getCodeSizeRegex(); - Pattern codeSizePattern = codeSizeRegex != null ? Pattern.compile(codeSizeRegex) : null; - String dataSizeRegex = config.getDataSizeRegex(); - Pattern dataSizePattern = dataSizeRegex != null ? Pattern.compile(dataSizeRegex) : null; - - if (codeSizePattern == null && dataSizePattern == null) { - return; - } - - int maxCodeSize = config.getMaxCodeSize(); - int maxDataSize = config.getMaxDataSize(); - - ProcessBuilder processBuilder = new ProcessBuilder().command(config.getSizeCommand()) - .directory(config.getBuildDirectory()).redirectErrorStream(true); - config.setEnvironment(processBuilder.environment()); - Process process = processBuilder.start(); - try (BufferedReader processOut = new BufferedReader(new InputStreamReader(process.getInputStream()))) { - for (String line = processOut.readLine(); line != null; line = processOut.readLine()) { - if (codeSizePattern != null) { - Matcher matcher = codeSizePattern.matcher(line); - if (matcher.matches()) { - codeSize += Integer.parseInt(matcher.group(1)); - } - } - if (dataSizePattern != null) { - Matcher matcher = dataSizePattern.matcher(line); - if (matcher.matches()) { - dataSize += Integer.parseInt(matcher.group(1)); - } - } - } - } - - console.writeOutput("Program store usage: " + codeSize); - if (maxCodeSize > 0) { - console.writeOutput(" of maximum " + maxCodeSize); - } - console.writeOutput(" bytes\n"); - - if (maxDataSize >= 0) { - console.writeOutput("Initial RAM usage: " + dataSize); - if (maxCodeSize > 0) { - console.writeOutput(" of maximum " + maxDataSize); - } - console.writeOutput(" bytes\n"); - } - } catch (IOException e) { - throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Checking sizes", e)); - } - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java new file mode 100644 index 00000000000..2f4fd2effef --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChain.java @@ -0,0 +1,62 @@ +package org.eclipse.cdt.arduino.core.internal.build; + +import org.eclipse.cdt.arduino.core.internal.Activator; +import org.eclipse.cdt.build.gcc.core.GCCToolChain; +import org.eclipse.cdt.core.build.ICBuildConfiguration; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChainProvider; +import org.eclipse.core.resources.IBuildConfiguration; +import org.eclipse.core.resources.IProject; +import org.eclipse.core.resources.ResourcesPlugin; +import org.eclipse.core.runtime.CoreException; +import org.eclipse.core.runtime.IStatus; +import org.eclipse.core.runtime.Status; + +public class ArduinoToolChain extends GCCToolChain { + + private final ArduinoBuildConfiguration buildConfig; + + public ArduinoToolChain(IToolChainProvider provider, ArduinoBuildConfiguration config) { + super(provider, config.getProject().getName() + '#' + config.getName()); + this.buildConfig = config; + } + + ArduinoToolChain(IToolChainProvider provider, String name) throws CoreException { + super(provider, name); + String[] segments = name.split("#"); //$NON-NLS-1$ + if (segments.length == 2) { + String projectName = segments[0]; + String configName = segments[1]; + + IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject(projectName); + if (project != null) { + ICBuildConfigurationManager configManager = Activator.getService(ICBuildConfigurationManager.class); + IBuildConfiguration config = configManager.getBuildConfiguration( + configManager.getProvider(ArduinoBuildConfigurationProvider.ID), project, configName); + ICBuildConfiguration cconfig = config.getAdapter(ICBuildConfiguration.class); + buildConfig = cconfig.getAdapter(ArduinoBuildConfiguration.class); + } else { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "No project")); + } + } else { + throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Bad Name")); + } + } + + @Override + public String getProperty(String key) { + // TODO architecture if I need it + if (key.equals(IToolChain.ATTR_OS)) { + return "arduino"; //$NON-NLS-1$ + } else { + return null; + } + } + + // TODO do I really need this? + public ArduinoBuildConfiguration getBuildConfig() { + return buildConfig; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java new file mode 100644 index 00000000000..79ecce03562 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/build/ArduinoToolChainProvider.java @@ -0,0 +1,21 @@ +package org.eclipse.cdt.arduino.core.internal.build; + +import org.eclipse.cdt.core.build.IToolChain; +import org.eclipse.cdt.core.build.IToolChainProvider; +import org.eclipse.core.runtime.CoreException; + +public class ArduinoToolChainProvider implements IToolChainProvider { + + public static final String ID = "org.eclipse.cdt.arduino.core.toolChainProvider"; //$NON-NLS-1$ + + @Override + public String getId() { + return ID; + } + + @Override + public IToolChain getToolChain(String name) throws CoreException { + return new ArduinoToolChain(this, name); + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleParser.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleParser.java deleted file mode 100644 index 582a7f485c7..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleParser.java +++ /dev/null @@ -1,60 +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.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; - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleService.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleService.java deleted file mode 100644 index 5ac7dba8731..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoConsoleService.java +++ /dev/null @@ -1,25 +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 - * - * 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; - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoErrorParser.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoErrorParser.java deleted file mode 100644 index 4adaac9fc85..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/console/ArduinoErrorParser.java +++ /dev/null @@ -1,83 +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.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; - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java index b3b1d361887..6ec1d0c9385 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/src/org/eclipse/cdt/arduino/core/internal/launch/ArduinoLaunchConfigurationDelegate.java @@ -15,7 +15,9 @@ 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.build.ArduinoBuildConfiguration; +import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfigurationProvider; import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection; +import org.eclipse.cdt.core.build.ICBuildConfigurationManager; import org.eclipse.core.resources.IProject; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IProgressMonitor; @@ -34,6 +36,9 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge 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 final ICBuildConfigurationManager buildConfigManager = Activator + .getService(ICBuildConfigurationManager.class); + @Override public ITargetedLaunch getLaunch(ILaunchConfiguration configuration, String mode, ILaunchTarget target) throws CoreException { @@ -49,7 +54,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge // 1. make sure proper build config is set active IProject project = configuration.getMappedResources()[0].getProject(); - ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, arduinoTarget, + ArduinoBuildConfiguration arduinoConfig = getArduinoConfiguration(project, mode, arduinoTarget, monitor); arduinoConfig.setActive(monitor); } @@ -81,7 +86,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge IProject project = (IProject) configuration.getMappedResources()[0]; // The build config - ArduinoBuildConfiguration arduinoConfig = ArduinoBuildConfiguration.getConfig(project, arduinoTarget, + ArduinoBuildConfiguration arduinoConfig = getArduinoConfiguration(project, mode, arduinoTarget, monitor); String[] uploadCmd = arduinoConfig.getUploadCommand(arduinoTarget.getPortName()); @@ -94,8 +99,9 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge ((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()); + ProcessBuilder processBuilder = new ProcessBuilder(uploadCmd) + .directory(arduinoConfig.getBuildDirectory().toFile()); + arduinoConfig.setBuildEnvironment(processBuilder.environment()); Process process = processBuilder.start(); DebugPlugin.newProcess(launch, process, cmdStr.toString()); } catch (IOException e) { @@ -104,4 +110,15 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationTarge } + public ArduinoBuildConfiguration getArduinoConfiguration(IProject project, String launchMode, + ArduinoRemoteConnection arduinoTarget, + IProgressMonitor monitor) throws CoreException { + ArduinoBuildConfigurationProvider provider = (ArduinoBuildConfigurationProvider) buildConfigManager + .getProvider(ArduinoBuildConfigurationProvider.ID); + ArduinoBuildConfiguration config = provider.getConfiguration(project, arduinoTarget, launchMode, monitor); + if (config == null) { + config = provider.createConfiguration(project, arduinoTarget, launchMode, monitor); + } + return config; + } } diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/Makefile index 1f0971bd120..48888521aa8 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/board.mk +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/Makefile @@ -91,7 +91,7 @@ size: <#list project_srcs as file> <#assign cpp = file?matches("(.*)\\.cpp")> <#if cpp> -${build_path}/project/${cpp?groups[1]}.cpp.o: ../${file} ${build_path}/project/${cpp?groups[1]}.cpp.d +${build_path}/project/${cpp?groups[1]}.cpp.o: ../../${file} ${build_path}/project/${cpp?groups[1]}.cpp.d @$(call mymkdir,$(dir $@)) ${recipe_cpp_o_pattern} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/arduino.cpp b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/arduino.cpp index ddfe4da79b6..ddfe4da79b6 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/arduino.cpp +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/arduino.cpp diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml new file mode 100644 index 00000000000..148f5c807ca --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.core/templates/cppsketch/manifest.xml @@ -0,0 +1,4 @@ +<templateManifest> + <file src="/templates/cppsketch/arduino.cpp" + dest="/${projectName}/${projectName}.cpp"/> +</templateManifest>
\ No newline at end of file diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF b/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF index 85291e2145f..c66654bacc6 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/META-INF/MANIFEST.MF @@ -19,7 +19,8 @@ Require-Bundle: org.eclipse.core.runtime, org.eclipse.remote.ui;bundle-version="2.0.0", org.eclipse.cdt.core, org.eclipse.cdt.native.serial;bundle-version="1.0.0", - org.eclipse.launchbar.remote.ui;bundle-version="1.0.0" + org.eclipse.launchbar.remote.ui;bundle-version="1.0.0", + org.eclipse.tools.templates.ui;bundle-version="1.0.0" Bundle-RequiredExecutionEnvironment: JavaSE-1.7 Bundle-ActivationPolicy: lazy Bundle-Vendor: %providerName diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/icons/arduino48.png b/toolchains/arduino/org.eclipse.cdt.arduino.ui/icons/arduino48.png Binary files differnew file mode 100644 index 00000000000..1fa5d248086 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/icons/arduino48.png diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml index 1a6410413b3..3e5c883c989 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/plugin.xml @@ -112,8 +112,7 @@ <view id="org.eclipse.remote.ui.view.connections" minimized="false" - ratio="0.75" - relationship="bottom" + relationship="stack" relative="org.eclipse.ui.navigator.ProjectExplorer"> </view> </perspectiveExtension> @@ -149,4 +148,23 @@ name="Arduino"> </wizard> </extension> + <extension + point="org.eclipse.tools.templates.ui.templates"> + <tag + id="org.eclipse.cdt.arduino.ui.tag" + label="Arduino"> + </tag> + <template + icon="icons/arduino48.png" + id="org.eclipse.cdt.arduino.ui.template.sketch" + label="Arduino C++ Sketch" + wizard="org.eclipse.cdt.arduino.ui.internal.project.NewArduinoCPPSketchWizard"> + <tagReference + id="org.eclipse.cdt.arduino.ui.tag"> + </tagReference> + <description> + A single C++ file with empty setup() and loop() functions. + </description> + </template> + </extension> </plugin> diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java deleted file mode 100644 index fc14c9fe2fc..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoConsole.java +++ /dev/null @@ -1,162 +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 - * - * 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); - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoErrorMatchListener.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoErrorMatchListener.java deleted file mode 100644 index b2113940093..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoErrorMatchListener.java +++ /dev/null @@ -1,38 +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.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); - } - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoHyperlink.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoHyperlink.java deleted file mode 100644 index 51927a45cf0..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoHyperlink.java +++ /dev/null @@ -1,44 +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.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); - } - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoPatternMatchListener.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoPatternMatchListener.java deleted file mode 100644 index ea222570f14..00000000000 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/launch/ArduinoPatternMatchListener.java +++ /dev/null @@ -1,50 +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.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(); - } - -} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoCPPSketchWizard.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoCPPSketchWizard.java new file mode 100644 index 00000000000..65b096de228 --- /dev/null +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoCPPSketchWizard.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * 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.ArduinoProjectGenerator; +import org.eclipse.jface.dialogs.Dialog; +import org.eclipse.swt.widgets.Composite; +import org.eclipse.tools.templates.core.IGenerator; +import org.eclipse.tools.templates.ui.TemplateWizard; +import org.eclipse.ui.dialogs.WizardNewProjectCreationPage; + +public class NewArduinoCPPSketchWizard extends TemplateWizard { + + private WizardNewProjectCreationPage mainPage; + + @Override + public void addPages() { + mainPage = new WizardNewProjectCreationPage("basicNewProjectPage") { //$NON-NLS-1$ + @Override + public void createControl(Composite parent) { + super.createControl(parent); + createWorkingSetGroup((Composite) getControl(), getSelection(), + new String[] { "org.eclipse.ui.resourceWorkingSetPage" }); //$NON-NLS-1$ + Dialog.applyDialogFont(getControl()); + } + }; + mainPage.setTitle("New Arduino Project"); //$NON-NLS-1$ + mainPage.setDescription("Specify properties of new Arduino project."); //$NON-NLS-1$ + this.addPage(mainPage); + } + + @Override + protected IGenerator getGenerator() { + ArduinoProjectGenerator generator = new ArduinoProjectGenerator("templates/cppsketch/manifest.xml"); //$NON-NLS-1$ + generator.setProjectName(mainPage.getProjectName()); + if (!mainPage.useDefaults()) { + generator.setLocationURI(mainPage.getLocationURI()); + } + return generator; + } + +} diff --git a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java index 1ad1f0df6d7..7280d958f74 100644 --- a/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java +++ b/toolchains/arduino/org.eclipse.cdt.arduino.ui/src/org/eclipse/cdt/arduino/ui/internal/project/NewArduinoProjectWizard.java @@ -7,55 +7,28 @@ *******************************************************************************/ package org.eclipse.cdt.arduino.ui.internal.project; -import org.eclipse.cdt.arduino.core.internal.ArduinoProjectGenerator; -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.Status; -import org.eclipse.core.runtime.jobs.Job; -import org.eclipse.ui.IWorkbenchPage; -import org.eclipse.ui.PartInitException; -import org.eclipse.ui.ide.IDE; +import org.eclipse.tools.templates.ui.TemplateSelectionPage; import org.eclipse.ui.wizards.newresource.BasicNewProjectResourceWizard; public class NewArduinoProjectWizard extends BasicNewProjectResourceWizard { + private static final String ARDUINO_TAG_ID = "org.eclipse.cdt.arduino.ui.tag"; //$NON-NLS-1$ + + private TemplateSelectionPage templateSelectionPage; + + public NewArduinoProjectWizard() { + setForcePreviousAndNextButtons(true); + } + @Override public void addPages() { - super.addPages(); + templateSelectionPage = new TemplateSelectionPage("templateSelection", ARDUINO_TAG_ID); //$NON-NLS-1$ + templateSelectionPage.setTitle("Template for New Arduino Project"); + this.addPage(templateSelectionPage); } @Override public boolean performFinish() { - if (!super.performFinish()) - return false; - - new Job(Messages.NewArduinoProjectWizard_0) { - @Override - protected IStatus run(IProgressMonitor monitor) { - try { - final ArduinoProjectGenerator generator = new ArduinoProjectGenerator(getNewProject()); - generator.generate(monitor); - getWorkbench().getDisplay().asyncExec(new Runnable() { - @Override - public void run() { - try { - IWorkbenchPage activePage = getWorkbench().getActiveWorkbenchWindow().getActivePage(); - IDE.openEditor(activePage, generator.getSourceFile()); - } catch (PartInitException e) { - Activator.getDefault().getLog().log(e.getStatus()); - } - } - }); - return Status.OK_STATUS; - } catch (CoreException e) { - return e.getStatus(); - } - } - }.schedule(); - return true; } |