1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-06-07 01:36:01 +02:00

Much progress on the Arduino build system.

Change-Id: I437621ed8af02abddc05852bf6c1b62b50f17a25
This commit is contained in:
Doug Schaefer 2015-08-10 23:33:15 -04:00 committed by Gerrit Code Review @ Eclipse.org
parent 64b26a87d5
commit 19629b7ab5
38 changed files with 1424 additions and 1288 deletions

View file

@ -89,13 +89,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
static String CONTAINER_INITIALIZER_EXTPOINT_ID = "PathEntryContainerInitializer"; //$NON-NLS-1$ static String CONTAINER_INITIALIZER_EXTPOINT_ID = "PathEntryContainerInitializer"; //$NON-NLS-1$
/** /**
* An empty array of strings indicating that a project doesn't have any prerequesite projects. * An empty array of strings indicating that a project doesn't have any
* prerequesite projects.
*/ */
static final String[] NO_PREREQUISITES = {}; static final String[] NO_PREREQUISITES = {};
/** /**
* pathentry containers pool accessing the Container is done synch with the class * pathentry containers pool accessing the Container is done synch with the
* class
*/ */
private static HashMap<ICProject, Map<IPath, IPathEntryContainer>> Containers = new HashMap<ICProject, Map<IPath, IPathEntryContainer>>(5); private static HashMap<ICProject, Map<IPath, IPathEntryContainer>> Containers = new HashMap<ICProject, Map<IPath, IPathEntryContainer>>(
5);
static final IPathEntry[] NO_PATHENTRIES = {}; static final IPathEntry[] NO_PATHENTRIES = {};
@ -178,14 +181,14 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
public IIncludeFileEntry[] getIncludeFileEntries(IPath resPath) throws CModelException { public IIncludeFileEntry[] getIncludeFileEntries(IPath resPath) throws CModelException {
ICElement celement = CoreModel.getDefault().create(resPath); ICElement celement = CoreModel.getDefault().create(resPath);
if (celement instanceof ITranslationUnit) { if (celement instanceof ITranslationUnit) {
return getIncludeFileEntries((ITranslationUnit)celement); return getIncludeFileEntries((ITranslationUnit) celement);
} }
if (celement != null) { if (celement != null) {
// Get project include file entries. // Get project include file entries.
List<IPathEntry> entryList = new ArrayList<IPathEntry>(); List<IPathEntry> entryList = new ArrayList<IPathEntry>();
ICProject cproject = celement.getCProject(); ICProject cproject = celement.getCProject();
ArrayList<IPathEntry> resolvedListEntries = getResolvedPathEntries(cproject, false); ArrayList<IPathEntry> resolvedListEntries = getResolvedPathEntries(cproject, false);
IPathEntry[] pathEntries= getCachedResolvedPathEntries(resolvedListEntries, cproject); IPathEntry[] pathEntries = getCachedResolvedPathEntries(resolvedListEntries, cproject);
for (int i = 0; i < pathEntries.length; ++i) { for (int i = 0; i < pathEntries.length; ++i) {
IPathEntry entry = pathEntries[i]; IPathEntry entry = pathEntries[i];
if ((entry.getEntryKind() & IPathEntry.CDT_INCLUDE_FILE) != 0) { if ((entry.getEntryKind() & IPathEntry.CDT_INCLUDE_FILE) != 0) {
@ -207,14 +210,14 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
public IIncludeEntry[] getIncludeEntries(IPath resPath) throws CModelException { public IIncludeEntry[] getIncludeEntries(IPath resPath) throws CModelException {
ICElement celement = CoreModel.getDefault().create(resPath); ICElement celement = CoreModel.getDefault().create(resPath);
if (celement instanceof ITranslationUnit) { if (celement instanceof ITranslationUnit) {
return getIncludeEntries((ITranslationUnit)celement); return getIncludeEntries((ITranslationUnit) celement);
} }
if (celement != null) { if (celement != null) {
// get project include entries // get project include entries
List<IPathEntry> entryList = new ArrayList<IPathEntry>(); List<IPathEntry> entryList = new ArrayList<IPathEntry>();
ICProject cproject = celement.getCProject(); ICProject cproject = celement.getCProject();
ArrayList<IPathEntry> resolvedListEntries = getResolvedPathEntries(cproject, false); ArrayList<IPathEntry> resolvedListEntries = getResolvedPathEntries(cproject, false);
IPathEntry[] pathEntries= getCachedResolvedPathEntries(resolvedListEntries, cproject); IPathEntry[] pathEntries = getCachedResolvedPathEntries(resolvedListEntries, cproject);
for (int i = 0; i < pathEntries.length; ++i) { for (int i = 0; i < pathEntries.length; ++i) {
IPathEntry entry = pathEntries[i]; IPathEntry entry = pathEntries[i];
if ((entry.getEntryKind() & IPathEntry.CDT_INCLUDE) != 0) { if ((entry.getEntryKind() & IPathEntry.CDT_INCLUDE) != 0) {
@ -233,30 +236,30 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return includes; return includes;
} }
public IMacroEntry[] getMacroEntries(IPath resPath) throws CModelException { public IMacroEntry[] getMacroEntries(IPath resPath) throws CModelException {
ICElement celement = CoreModel.getDefault().create(resPath); ICElement celement = CoreModel.getDefault().create(resPath);
if (celement instanceof ITranslationUnit) { if (celement instanceof ITranslationUnit) {
return getMacroEntries((ITranslationUnit)celement); return getMacroEntries((ITranslationUnit) celement);
} }
if (celement != null) { if (celement != null) {
// get project macro entries // get project macro entries
List<IPathEntry> entryList = new ArrayList<IPathEntry>(); List<IPathEntry> entryList = new ArrayList<IPathEntry>();
ICProject cproject = celement.getCProject(); ICProject cproject = celement.getCProject();
ArrayList<IPathEntry> resolvedListEntries = getResolvedPathEntries(cproject, false); ArrayList<IPathEntry> resolvedListEntries = getResolvedPathEntries(cproject, false);
IPathEntry[] pathEntries= getCachedResolvedPathEntries(resolvedListEntries, cproject); IPathEntry[] pathEntries = getCachedResolvedPathEntries(resolvedListEntries, cproject);
for (int i = 0; i < pathEntries.length; ++i) { for (int i = 0; i < pathEntries.length; ++i) {
IPathEntry entry = pathEntries[i]; IPathEntry entry = pathEntries[i];
if ((entry.getEntryKind() & IPathEntry.CDT_MACRO) != 0) { if ((entry.getEntryKind() & IPathEntry.CDT_MACRO) != 0) {
entryList.add(entry); entryList.add(entry);
} }
} }
IMacroEntry[] macros= entryList.toArray(new IMacroEntry[entryList.size()]); IMacroEntry[] macros = entryList.toArray(new IMacroEntry[entryList.size()]);
return macros; return macros;
} }
return NO_MACRO_ENTRIES; return NO_MACRO_ENTRIES;
} }
private IMacroEntry[] getMacroEntries(ITranslationUnit cunit) throws CModelException { private IMacroEntry[] getMacroEntries(ITranslationUnit cunit) throws CModelException {
ArrayList<IPathEntry> macroList = new ArrayList<IPathEntry>(); ArrayList<IPathEntry> macroList = new ArrayList<IPathEntry>();
ICProject cproject = cunit.getCProject(); ICProject cproject = cunit.getCProject();
IPath resPath = cunit.getPath(); IPath resPath = cunit.getPath();
@ -271,8 +274,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IPathEntryContainer[] containers = getPathEntryContainers(cproject); IPathEntryContainer[] containers = getPathEntryContainers(cproject);
for (int i = 0; i < containers.length; ++i) { for (int i = 0; i < containers.length; ++i) {
if (containers[i] instanceof IPathEntryContainerExtension) { if (containers[i] instanceof IPathEntryContainerExtension) {
IPathEntryContainerExtension extension = (IPathEntryContainerExtension)containers[i]; IPathEntryContainerExtension extension = (IPathEntryContainerExtension) containers[i];
IPathEntry[] incs = extension.getPathEntries(resPath, IPathEntry.CDT_MACRO); IPathEntry[] incs = extension.getPathEntries(resPath, IPathEntry.CDT_MACRO);
macroList.addAll(Arrays.asList(incs)); macroList.addAll(Arrays.asList(incs));
} }
} }
@ -282,7 +285,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// For the macros the closest symbol will override // For the macros the closest symbol will override
// /projec/src/file.c --> NDEBUG=1 // /projec/src/file.c --> NDEBUG=1
// /project/src --> NDEBUG=0 // /project/src --> NDEBUG=0
// //
// We will use NDEBUG=1 only // We will use NDEBUG=1 only
int count = resPath.segmentCount(); int count = resPath.segmentCount();
@ -306,13 +309,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) { if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) {
IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath()); IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath());
if (res != null && res.getType() == IResource.PROJECT) { if (res != null && res.getType() == IResource.PROJECT) {
ICProject refCProject = CoreModel.getDefault().create((IProject)res); ICProject refCProject = CoreModel.getDefault().create((IProject) res);
if (refCProject != null) { if (refCProject != null) {
IPathEntry[] projEntries = refCProject.getResolvedPathEntries(); IPathEntry[] projEntries = refCProject.getResolvedPathEntries();
for (IPathEntry projEntry : projEntries) { for (IPathEntry projEntry : projEntries) {
if (projEntry.isExported()) { if (projEntry.isExported()) {
if (projEntry.getEntryKind() == IPathEntry.CDT_MACRO) { if (projEntry.getEntryKind() == IPathEntry.CDT_MACRO) {
IMacroEntry macro = (IMacroEntry)entry; IMacroEntry macro = (IMacroEntry) entry;
String key = macro.getMacroName(); String key = macro.getMacroName();
if (!symbolMap.containsKey(key)) { if (!symbolMap.containsKey(key)) {
symbolMap.put(key, macro); symbolMap.put(key, macro);
@ -328,15 +331,15 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return symbolMap.values().toArray(NO_MACRO_ENTRIES); return symbolMap.values().toArray(NO_MACRO_ENTRIES);
} }
public IMacroFileEntry[] getMacroFileEntries(IPath resPath) throws CModelException { public IMacroFileEntry[] getMacroFileEntries(IPath resPath) throws CModelException {
ICElement celement = CoreModel.getDefault().create(resPath); ICElement celement = CoreModel.getDefault().create(resPath);
if (celement instanceof ITranslationUnit) { if (celement instanceof ITranslationUnit) {
return getMacroFileEntries((ITranslationUnit)celement); return getMacroFileEntries((ITranslationUnit) celement);
} }
return NO_MACRO_FILE_ENTRIES; return NO_MACRO_FILE_ENTRIES;
} }
public IMacroFileEntry[] getMacroFileEntries(ITranslationUnit cunit) throws CModelException { public IMacroFileEntry[] getMacroFileEntries(ITranslationUnit cunit) throws CModelException {
List<IPathEntry> list = getPathEntries(cunit, IPathEntry.CDT_MACRO_FILE); List<IPathEntry> list = getPathEntries(cunit, IPathEntry.CDT_MACRO_FILE);
IMacroFileEntry[] macFiles = list.toArray(new IMacroFileEntry[list.size()]); IMacroFileEntry[] macFiles = list.toArray(new IMacroFileEntry[list.size()]);
return macFiles; return macFiles;
@ -357,7 +360,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IPathEntryContainer[] containers = getPathEntryContainers(cproject); IPathEntryContainer[] containers = getPathEntryContainers(cproject);
for (int i = 0; i < containers.length; ++i) { for (int i = 0; i < containers.length; ++i) {
if (containers[i] instanceof IPathEntryContainerExtension) { if (containers[i] instanceof IPathEntryContainerExtension) {
IPathEntryContainerExtension extension = (IPathEntryContainerExtension)containers[i]; IPathEntryContainerExtension extension = (IPathEntryContainerExtension) containers[i];
IPathEntry[] incs = extension.getPathEntries(resPath, type); IPathEntry[] incs = extension.getPathEntries(resPath, type);
entryList.addAll(Arrays.asList(incs)); entryList.addAll(Arrays.asList(incs));
} }
@ -369,10 +372,10 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// We need to reorder the include/macros: // We need to reorder the include/macros:
// includes with the closest match to the resource will come first // includes with the closest match to the resource will come first
// /project/src/file.c --> /usr/local/include // /project/src/file.c --> /usr/local/include
// /project --> /usr/include // /project --> /usr/include
// //
// /usr/local/include must come first. // /usr/local/include must come first.
// //
int count = resPath.segmentCount(); int count = resPath.segmentCount();
for (int i = 0; i < count; i++) { for (int i = 0; i < count; i++) {
@ -392,7 +395,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) { if (entry != null && entry.getEntryKind() == IPathEntry.CDT_PROJECT) {
IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath()); IResource res = cproject.getCModel().getWorkspace().getRoot().findMember(entry.getPath());
if (res != null && res.getType() == IResource.PROJECT) { if (res != null && res.getType() == IResource.PROJECT) {
ICProject refCProject = CoreModel.getDefault().create((IProject)res); ICProject refCProject = CoreModel.getDefault().create((IProject) res);
if (refCProject != null) { if (refCProject != null) {
IPathEntry[] projEntries = refCProject.getResolvedPathEntries(); IPathEntry[] projEntries = refCProject.getResolvedPathEntries();
for (IPathEntry projEntry : projEntries) { for (IPathEntry projEntry : projEntries) {
@ -411,6 +414,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/** /**
* Return the cached entries, if no cache null. * Return the cached entries, if no cache null.
*
* @param cproject * @param cproject
*/ */
protected IPathEntry[] getCachedResolvedPathEntries(ICProject cproject) { protected IPathEntry[] getCachedResolvedPathEntries(ICProject cproject) {
@ -425,26 +429,26 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return null; return null;
} }
public PathEntryResolveInfo getResolveInfo(ICProject cproject, boolean useCache) throws CModelException{ public PathEntryResolveInfo getResolveInfo(ICProject cproject, boolean useCache) throws CModelException {
PathEntryResolveInfo info = resolvedInfoMap.get(cproject); PathEntryResolveInfo info = resolvedInfoMap.get(cproject);
if (info == null && useCache){ if (info == null && useCache) {
getResolvedPathEntries(cproject); getResolvedPathEntries(cproject);
info = resolvedInfoMap.get(cproject); info = resolvedInfoMap.get(cproject);
} }
if (info == null || !useCache || !getResolveInfoValidState(cproject)){ if (info == null || !useCache || !getResolveInfoValidState(cproject)) {
Object[] resolved = getResolvedPathEntries(cproject, false, false); Object[] resolved = getResolvedPathEntries(cproject, false, false);
if (resolved != null) if (resolved != null)
info = (PathEntryResolveInfo)resolved[1]; info = (PathEntryResolveInfo) resolved[1];
} }
return info; return info;
} }
private void setResolveInfoValidState(ICProject cproject, boolean valid){ private void setResolveInfoValidState(ICProject cproject, boolean valid) {
Object v = valid ? null : Boolean.FALSE; Object v = valid ? null : Boolean.FALSE;
resolveInfoValidState.set(cproject, v); resolveInfoValidState.set(cproject, v);
} }
private boolean getResolveInfoValidState(ICProject cproject){ private boolean getResolveInfoValidState(ICProject cproject) {
return resolveInfoValidState.get(cproject) == null; return resolveInfoValidState.get(cproject) == null;
} }
@ -461,12 +465,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return null; return null;
} }
private IPathEntry[] getCachedResolvedPathEntries(ArrayList<IPathEntry> resolvedListEntries, ICProject cproject) throws CModelException { private IPathEntry[] getCachedResolvedPathEntries(ArrayList<IPathEntry> resolvedListEntries,
ICProject cproject) throws CModelException {
IPathEntry[] entries = resolvedListEntries.toArray(NO_PATHENTRIES); IPathEntry[] entries = resolvedListEntries.toArray(NO_PATHENTRIES);
boolean hasContainerExtension = false; boolean hasContainerExtension = false;
for (IPathEntry entry : entries) { for (IPathEntry entry : entries) {
if (entry.getEntryKind() == IPathEntry.CDT_CONTAINER) { if (entry.getEntryKind() == IPathEntry.CDT_CONTAINER) {
IContainerEntry centry = (IContainerEntry)entry; IContainerEntry centry = (IContainerEntry) entry;
IPathEntryContainer container = getPathEntryContainer(centry, cproject); IPathEntryContainer container = getPathEntryContainer(centry, cproject);
if (container instanceof IPathEntryContainerExtension) { if (container instanceof IPathEntryContainerExtension) {
hasContainerExtension = true; hasContainerExtension = true;
@ -479,13 +484,14 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
ArrayList<IPathEntry> listEntries = new ArrayList<IPathEntry>(entries.length); ArrayList<IPathEntry> listEntries = new ArrayList<IPathEntry>(entries.length);
for (int i = 0; i < entries.length; ++i) { for (int i = 0; i < entries.length; ++i) {
if (entries[i].getEntryKind() == IPathEntry.CDT_CONTAINER) { if (entries[i].getEntryKind() == IPathEntry.CDT_CONTAINER) {
IContainerEntry centry = (IContainerEntry)entries[i]; IContainerEntry centry = (IContainerEntry) entries[i];
IPathEntryContainer container = getPathEntryContainer(centry, cproject); IPathEntryContainer container = getPathEntryContainer(centry, cproject);
if (container != null) { if (container != null) {
IPathEntry[] containerEntries = container.getPathEntries(); IPathEntry[] containerEntries = container.getPathEntries();
if (containerEntries != null) { if (containerEntries != null) {
for (IPathEntry containerEntry : containerEntries) { for (IPathEntry containerEntry : containerEntries) {
IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath, containerEntry); IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath,
containerEntry);
listEntries.add(newEntry); listEntries.add(newEntry);
} }
} }
@ -506,7 +512,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
/** /**
* This method will not expand container extending IPathEntryContainerExtension * This method will not expand container extending
* IPathEntryContainerExtension
* *
* @param cproject * @param cproject
* @param generateMarkers * @param generateMarkers
@ -514,17 +521,19 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
* @throws CModelException * @throws CModelException
*/ */
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private ArrayList<IPathEntry> getResolvedPathEntries(ICProject cproject, boolean generateMarkers) throws CModelException { private ArrayList<IPathEntry> getResolvedPathEntries(ICProject cproject, boolean generateMarkers)
throws CModelException {
Object[] result = getResolvedPathEntries(cproject, generateMarkers, true); Object[] result = getResolvedPathEntries(cproject, generateMarkers, true);
if (result != null) if (result != null)
return (ArrayList<IPathEntry>) result[0]; return (ArrayList<IPathEntry>) result[0];
return null; return null;
} }
private Object[] getResolvedPathEntries(ICProject cproject, boolean generateMarkers, boolean useCache) throws CModelException { private Object[] getResolvedPathEntries(ICProject cproject, boolean generateMarkers, boolean useCache)
throws CModelException {
ArrayList<IPathEntry> resolvedEntries = null; ArrayList<IPathEntry> resolvedEntries = null;
PathEntryResolveInfo rInfo = null; PathEntryResolveInfo rInfo = null;
if (useCache){ if (useCache) {
resolvedEntries = resolvedMap.get(cproject); resolvedEntries = resolvedMap.get(cproject);
rInfo = resolvedInfoMap.get(cproject); rInfo = resolvedInfoMap.get(cproject);
} }
@ -536,17 +545,19 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
for (IPathEntry entry : rawEntries) { for (IPathEntry entry : rawEntries) {
// Expand the containers. // Expand the containers.
if (entry.getEntryKind() == IPathEntry.CDT_CONTAINER) { if (entry.getEntryKind() == IPathEntry.CDT_CONTAINER) {
IContainerEntry centry = (IContainerEntry)entry; IContainerEntry centry = (IContainerEntry) entry;
IPathEntryContainer container = getPathEntryContainer(centry, cproject); IPathEntryContainer container = getPathEntryContainer(centry, cproject);
if (container != null) { if (container != null) {
// For backward compatibility we need to expand and cache container that // For backward compatibility we need to expand and
// cache container that
// are not IPathEntryContainerExtension. // are not IPathEntryContainerExtension.
if (!(container instanceof IPathEntryContainerExtension)) { if (!(container instanceof IPathEntryContainerExtension)) {
IPathEntry[] containerEntries = container.getPathEntries(); IPathEntry[] containerEntries = container.getPathEntries();
List<IPathEntry> resolvedList = new ArrayList<IPathEntry>(); List<IPathEntry> resolvedList = new ArrayList<IPathEntry>();
if (containerEntries != null) { if (containerEntries != null) {
for (IPathEntry containerEntry : containerEntries) { for (IPathEntry containerEntry : containerEntries) {
IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath, containerEntry); IPathEntry newEntry = PathEntryUtil.cloneEntryAndExpand(projectPath,
containerEntry);
resolvedEntries.add(newEntry); resolvedEntries.add(newEntry);
resolvedList.add(newEntry); resolvedList.add(newEntry);
} }
@ -603,7 +614,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
rInfo = new PathEntryResolveInfo(resolveInfoList); rInfo = new PathEntryResolveInfo(resolveInfoList);
if (useCache){ if (useCache) {
resolvedMap.put(cproject, resolvedEntries); resolvedMap.put(cproject, resolvedEntries);
resolvedInfoMap.put(cproject, rInfo); resolvedInfoMap.put(cproject, rInfo);
} }
@ -611,10 +622,12 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return new Object[] { resolvedEntries, rInfo }; return new Object[] { resolvedEntries, rInfo };
} }
public void setRawPathEntries(ICProject cproject, IPathEntry[] newEntries, IProgressMonitor monitor) throws CModelException { public void setRawPathEntries(ICProject cproject, IPathEntry[] newEntries, IProgressMonitor monitor)
throws CModelException {
try { try {
IPathEntry[] oldResolvedEntries = getCachedResolvedPathEntries(cproject); IPathEntry[] oldResolvedEntries = getCachedResolvedPathEntries(cproject);
SetPathEntriesOperation op = new SetPathEntriesOperation(cproject, oldResolvedEntries, newEntries); SetPathEntriesOperation op = new SetPathEntriesOperation(cproject, oldResolvedEntries,
newEntries);
op.runOperation(monitor); op.runOperation(monitor);
} catch (CoreException e) { } catch (CoreException e) {
throw new CModelException(e); throw new CModelException(e);
@ -625,7 +638,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
IProject project = cproject.getProject(); IProject project = cproject.getProject();
// Check if the Project is accessible. // Check if the Project is accessible.
if (!CoreModel.hasCNature(project) && !CoreModel.hasCCNature(project)) { if (!CoreModel.hasCNature(project) && !CoreModel.hasCCNature(project)) {
throw new CModelException(new CModelStatus(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST)); throw new CModelException(
new CModelStatus(ICModelStatusConstants.ELEMENT_DOES_NOT_EXIST, cproject));
} }
IPathEntry[] pathEntries; IPathEntry[] pathEntries;
try { try {
@ -666,17 +680,19 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return pathEntries; return pathEntries;
} }
public void setPathEntryContainer(ICProject[] affectedProjects, IPathEntryContainer newContainer, IProgressMonitor monitor) public void setPathEntryContainer(ICProject[] affectedProjects, IPathEntryContainer newContainer,
throws CModelException { IProgressMonitor monitor) throws CModelException {
SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects, newContainer); SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects,
newContainer);
op.runOperation(monitor); op.runOperation(monitor);
} }
public void clearPathEntryContainer(ICProject[] affectedProjects, IPath containerPath , IProgressMonitor monitor) public void clearPathEntryContainer(ICProject[] affectedProjects, IPath containerPath,
throws CModelException { IProgressMonitor monitor) throws CModelException {
SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects, containerPath); SetPathEntryContainerOperation op = new SetPathEntryContainerOperation(affectedProjects,
containerPath);
op.runOperation(monitor); op.runOperation(monitor);
} }
@ -685,44 +701,49 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
Map<IPath, IPathEntryContainer> projectContainers = Containers.get(cproject); Map<IPath, IPathEntryContainer> projectContainers = Containers.get(cproject);
if (projectContainers != null) { if (projectContainers != null) {
Collection<IPathEntryContainer> collection = projectContainers.values(); Collection<IPathEntryContainer> collection = projectContainers.values();
pcs= collection.toArray(NO_PATHENTRYCONTAINERS); pcs = collection.toArray(NO_PATHENTRYCONTAINERS);
} }
return pcs; return pcs;
} }
public IPathEntryContainer getPathEntryContainer(IContainerEntry entry, ICProject cproject) throws CModelException { public IPathEntryContainer getPathEntryContainer(IContainerEntry entry, ICProject cproject)
throws CModelException {
return getPathEntryContainer(entry.getPath(), cproject); return getPathEntryContainer(entry.getPath(), cproject);
} }
public IPathEntryContainer getPathEntryContainer(final IPath containerPath, final ICProject project) throws CModelException { public IPathEntryContainer getPathEntryContainer(final IPath containerPath, final ICProject project)
throws CModelException {
// Try the cache. // Try the cache.
IPathEntryContainer container = containerGet(project, containerPath, true); IPathEntryContainer container = containerGet(project, containerPath, true);
if (container instanceof PathEntryContainerLock) { if (container instanceof PathEntryContainerLock) {
boolean runInitializer = false; boolean runInitializer = false;
PathEntryContainerLock lock = (PathEntryContainerLock)container; PathEntryContainerLock lock = (PathEntryContainerLock) container;
synchronized (lock) { synchronized (lock) {
if (!lock.isContainerInitialize()) { if (!lock.isContainerInitialize()) {
runInitializer = true; runInitializer = true;
lock.setContainerInitialize(runInitializer); lock.setContainerInitialize(runInitializer);
} else if (! Thread.holdsLock(lock)){ } else if (!Thread.holdsLock(lock)) {
// FIXME: Use Thread.holdsLock(lock) to break the cycle. // FIXME: Use Thread.holdsLock(lock) to break the cycle.
// This seem to happend when the container(say the auto discovery) // This seem to happend when the container(say the auto
// trigger a resource change, the CoreModel will try to get the pathentries .. deadlock. // discovery)
// trigger a resource change, the CoreModel will try to get
// the pathentries .. deadlock.
// Wait for the inialization to finish. // Wait for the inialization to finish.
while (containerGet(project, containerPath, true) instanceof PathEntryContainerLock) { while (containerGet(project, containerPath, true) instanceof PathEntryContainerLock) {
try { try {
lock.wait(); lock.wait();
} catch (InterruptedException e) { } catch (InterruptedException e) {
//e.printStackTrace(); // e.printStackTrace();
} }
} }
} }
} }
if (runInitializer) { if (runInitializer) {
// Remove the lock. // Remove the lock.
final PathEntryContainerInitializer initializer = getPathEntryContainerInitializer(containerPath.segment(0)); final PathEntryContainerInitializer initializer = getPathEntryContainerInitializer(
final boolean[] ok = {false}; containerPath.segment(0));
final boolean[] ok = { false };
if (initializer != null) { if (initializer != null) {
// wrap initializer call with Safe runnable in case // wrap initializer call with Safe runnable in case
// initializer would be // initializer would be
@ -743,7 +764,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
}); });
} }
if (!ok[0]) { if (!ok[0]) {
containerPut(project, containerPath, null); // flush and notify containerPut(project, containerPath, null); // flush and
// notify
} }
} }
// Retrieve new value // Retrieve new value
@ -754,16 +776,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/** /**
* Helper method finding the container initializer registered for a given * Helper method finding the container initializer registered for a given
* container ID or <code>null</code> if none was found while iterating * container ID or <code>null</code> if none was found while iterating over
* over the contributions to extension point to the extension point * the contributions to extension point to the extension point
* "org.eclipse.cdt.core.PathEntryContainerInitializer". * "org.eclipse.cdt.core.PathEntryContainerInitializer".
* <p> * <p>
* A containerID is the first segment of any container path, used to * A containerID is the first segment of any container path, used to
* identify the registered container initializer. * identify the registered container initializer.
* <p> * <p>
* *
* @param containerID - * @param containerID
* a containerID identifying a registered initializer * - a containerID identifying a registered initializer
* @return PathEntryContainerInitializer - the registered container * @return PathEntryContainerInitializer - the registered container
* initializer or <code>null</code> if none was found. * initializer or <code>null</code> if none was found.
*/ */
@ -784,7 +806,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
try { try {
Object execExt = configElement.createExecutableExtension("class"); //$NON-NLS-1$ Object execExt = configElement.createExecutableExtension("class"); //$NON-NLS-1$
if (execExt instanceof PathEntryContainerInitializer) { if (execExt instanceof PathEntryContainerInitializer) {
return (PathEntryContainerInitializer)execExt; return (PathEntryContainerInitializer) execExt;
} }
} catch (CoreException e) { } catch (CoreException e) {
// Executable extension could not be created: // Executable extension could not be created:
@ -797,7 +819,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return null; return null;
} }
synchronized IPathEntryContainer containerGet(ICProject cproject, IPath containerPath, boolean bCreateLock) { synchronized IPathEntryContainer containerGet(ICProject cproject, IPath containerPath,
boolean bCreateLock) {
Map<IPath, IPathEntryContainer> projectContainers = Containers.get(cproject); Map<IPath, IPathEntryContainer> projectContainers = Containers.get(cproject);
if (projectContainers == null) { if (projectContainers == null) {
projectContainers = new HashMap<IPath, IPathEntryContainer>(); projectContainers = new HashMap<IPath, IPathEntryContainer>();
@ -835,7 +858,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
Containers.remove(cproject); Containers.remove(cproject);
} }
public void pathEntryContainerUpdates(IPathEntryContainerExtension container, PathEntryContainerChanged[] events, IProgressMonitor monitor) { public void pathEntryContainerUpdates(IPathEntryContainerExtension container,
PathEntryContainerChanged[] events, IProgressMonitor monitor) {
PathEntryContainerUpdatesOperation op = new PathEntryContainerUpdatesOperation(container, events); PathEntryContainerUpdatesOperation op = new PathEntryContainerUpdatesOperation(container, events);
try { try {
op.runOperation(monitor); op.runOperation(monitor);
@ -882,7 +906,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// Do not do this for container, the path is the ID. // Do not do this for container, the path is the ID.
if (kind != IPathEntry.CDT_CONTAINER) { if (kind != IPathEntry.CDT_CONTAINER) {
// Translate to project relative from absolute (unless a device path) // Translate to project relative from absolute (unless a device
// path)
if (resourcePath.isAbsolute()) { if (resourcePath.isAbsolute()) {
if (projectPath != null && projectPath.isPrefixOf(resourcePath)) { if (projectPath != null && projectPath.isPrefixOf(resourcePath)) {
if (resourcePath.segment(0).equals(projectPath.segment(0))) { if (resourcePath.segment(0).equals(projectPath.segment(0))) {
@ -898,84 +923,85 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// Specifics to the entries // Specifics to the entries
IPathEntry entry; IPathEntry entry;
switch (kind) { switch (kind) {
case IPathEntry.CDT_INCLUDE: { case IPathEntry.CDT_INCLUDE: {
IIncludeEntry include = (IIncludeEntry)pathEntry; IIncludeEntry include = (IIncludeEntry) pathEntry;
IPath baseRef = include.getBaseReference(); IPath baseRef = include.getBaseReference();
if (baseRef == null || baseRef.isEmpty()) { if (baseRef == null || baseRef.isEmpty()) {
entry = CoreModel.newIncludeEntry(resourcePath, include.getBasePath(), include.getIncludePath(), entry = CoreModel.newIncludeEntry(resourcePath, include.getBasePath(),
include.isSystemInclude(), include.getExclusionPatterns(), include.isExported()); include.getIncludePath(), include.isSystemInclude(),
} else { include.getExclusionPatterns(), include.isExported());
entry = CoreModel.newIncludeRefEntry(resourcePath, baseRef, include.getIncludePath()); } else {
} entry = CoreModel.newIncludeRefEntry(resourcePath, baseRef, include.getIncludePath());
break;
} }
case IPathEntry.CDT_INCLUDE_FILE: { break;
IIncludeFileEntry includeFile = (IIncludeFileEntry)pathEntry; }
entry = CoreModel.newIncludeFileEntry(resourcePath, includeFile.getBasePath(), case IPathEntry.CDT_INCLUDE_FILE: {
includeFile.getBaseReference(), includeFile.getIncludeFilePath(), IIncludeFileEntry includeFile = (IIncludeFileEntry) pathEntry;
includeFile.getExclusionPatterns(), includeFile.isExported()); entry = CoreModel.newIncludeFileEntry(resourcePath, includeFile.getBasePath(),
break; includeFile.getBaseReference(), includeFile.getIncludeFilePath(),
} includeFile.getExclusionPatterns(), includeFile.isExported());
case IPathEntry.CDT_LIBRARY: { break;
ILibraryEntry library = (ILibraryEntry)pathEntry; }
IPath sourcePath = library.getSourceAttachmentPath(); case IPathEntry.CDT_LIBRARY: {
if (sourcePath != null) { ILibraryEntry library = (ILibraryEntry) pathEntry;
// Translate to project relative from absolute IPath sourcePath = library.getSourceAttachmentPath();
if (projectPath != null && projectPath.isPrefixOf(sourcePath)) { if (sourcePath != null) {
if (sourcePath.segment(0).equals(projectPath.segment(0))) { // Translate to project relative from absolute
sourcePath = sourcePath.removeFirstSegments(1); if (projectPath != null && projectPath.isPrefixOf(sourcePath)) {
sourcePath = sourcePath.makeRelative(); if (sourcePath.segment(0).equals(projectPath.segment(0))) {
} sourcePath = sourcePath.removeFirstSegments(1);
sourcePath = sourcePath.makeRelative();
} }
} }
IPath baseRef = library.getBaseReference();
if (baseRef == null || baseRef.isEmpty()) {
entry = CoreModel.newLibraryEntry(resourcePath, library.getBasePath(), library.getLibraryPath(),
sourcePath, library.getSourceAttachmentRootPath(), library.getSourceAttachmentPrefixMapping(),
library.isExported());
} else {
entry = CoreModel.newLibraryRefEntry(resourcePath, baseRef, library.getLibraryPath());
}
break;
} }
case IPathEntry.CDT_MACRO: { IPath baseRef = library.getBaseReference();
IMacroEntry macro = (IMacroEntry)pathEntry; if (baseRef == null || baseRef.isEmpty()) {
IPath baseRef = macro.getBaseReference(); entry = CoreModel.newLibraryEntry(resourcePath, library.getBasePath(),
if (baseRef == null || baseRef.isEmpty()) { library.getLibraryPath(), sourcePath, library.getSourceAttachmentRootPath(),
entry = CoreModel.newMacroEntry(resourcePath, macro.getMacroName(), macro.getMacroValue(), library.getSourceAttachmentPrefixMapping(), library.isExported());
macro.getExclusionPatterns(), macro.isExported()); } else {
} else { entry = CoreModel.newLibraryRefEntry(resourcePath, baseRef, library.getLibraryPath());
entry = CoreModel.newMacroRefEntry(resourcePath, baseRef, macro.getMacroName());
}
break;
} }
case IPathEntry.CDT_MACRO_FILE: { break;
IMacroFileEntry macro = (IMacroFileEntry)pathEntry; }
entry = CoreModel.newMacroFileEntry(resourcePath, macro.getBasePath(), case IPathEntry.CDT_MACRO: {
macro.getBaseReference(), macro.getMacroFilePath(), IMacroEntry macro = (IMacroEntry) pathEntry;
IPath baseRef = macro.getBaseReference();
if (baseRef == null || baseRef.isEmpty()) {
entry = CoreModel.newMacroEntry(resourcePath, macro.getMacroName(), macro.getMacroValue(),
macro.getExclusionPatterns(), macro.isExported()); macro.getExclusionPatterns(), macro.isExported());
break; } else {
entry = CoreModel.newMacroRefEntry(resourcePath, baseRef, macro.getMacroName());
} }
case IPathEntry.CDT_OUTPUT: { break;
IOutputEntry out = (IOutputEntry)pathEntry; }
entry = CoreModel.newOutputEntry(resourcePath, out.getExclusionPatterns()); case IPathEntry.CDT_MACRO_FILE: {
break; IMacroFileEntry macro = (IMacroFileEntry) pathEntry;
} entry = CoreModel.newMacroFileEntry(resourcePath, macro.getBasePath(),
case IPathEntry.CDT_PROJECT: { macro.getBaseReference(), macro.getMacroFilePath(), macro.getExclusionPatterns(),
IProjectEntry projEntry = (IProjectEntry)pathEntry; macro.isExported());
entry = CoreModel.newProjectEntry(projEntry.getPath(), projEntry.isExported()); break;
break; }
} case IPathEntry.CDT_OUTPUT: {
case IPathEntry.CDT_SOURCE: { IOutputEntry out = (IOutputEntry) pathEntry;
ISourceEntry source = (ISourceEntry)pathEntry; entry = CoreModel.newOutputEntry(resourcePath, out.getExclusionPatterns());
entry = CoreModel.newSourceEntry(resourcePath, source.getExclusionPatterns()); break;
break; }
} case IPathEntry.CDT_PROJECT: {
case IPathEntry.CDT_CONTAINER: IProjectEntry projEntry = (IProjectEntry) pathEntry;
entry = CoreModel.newContainerEntry(pathEntry.getPath(), pathEntry.isExported()); entry = CoreModel.newProjectEntry(projEntry.getPath(), projEntry.isExported());
break; break;
default: }
entry = pathEntry; case IPathEntry.CDT_SOURCE: {
ISourceEntry source = (ISourceEntry) pathEntry;
entry = CoreModel.newSourceEntry(resourcePath, source.getExclusionPatterns());
break;
}
case IPathEntry.CDT_CONTAINER:
entry = CoreModel.newContainerEntry(pathEntry.getPath(), pathEntry.isExported());
break;
default:
entry = pathEntry;
} }
list.add(entry); list.add(entry);
} }
@ -993,9 +1019,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
/** /**
* Collects path entry errors for each project and generates error markers for these errors * Collects path entry errors for each project and generates error markers
* @param project - Project with path entry errors * for these errors
* @param problems - The path entry errors associated with the project *
* @param project
* - Project with path entry errors
* @param problems
* - The path entry errors associated with the project
*/ */
public void addProblemMarkers(final IProject project, final ICModelStatus[] problems) { public void addProblemMarkers(final IProject project, final ICModelStatus[] problems) {
PathEntryProblem problem = new PathEntryProblem(project, problems); PathEntryProblem problem = new PathEntryProblem(project, problems);
@ -1025,7 +1055,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
} }
private boolean needDelta(ICProject cproject){ private boolean needDelta(ICProject cproject) {
try { try {
PathEntryStoreProxy store = (PathEntryStoreProxy) getPathEntryStore(cproject.getProject(), false); PathEntryStoreProxy store = (PathEntryStoreProxy) getPathEntryStore(cproject.getProject(), false);
return store == null || !(store.getStore() instanceof ConfigBasedPathEntryStore); return store == null || !(store.getStore() instanceof ConfigBasedPathEntryStore);
@ -1034,7 +1064,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return false; return false;
} }
public ICElementDelta[] generatePathEntryDeltas(ICProject cproject, IPathEntry[] oldEntries, IPathEntry[] newEntries) { public ICElementDelta[] generatePathEntryDeltas(ICProject cproject, IPathEntry[] oldEntries,
IPathEntry[] newEntries) {
if (!needDelta(cproject)) if (!needDelta(cproject))
return new ICElementDelta[0]; return new ICElementDelta[0];
@ -1096,7 +1127,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
} }
} }
// They may have remove some duplications, catch here .. consider it as reordering. // They may have remove some duplications, catch here .. consider it as
// reordering.
if (list.size() == 0 && oldEntries.length != newEntries.length) { if (list.size() == 0 && oldEntries.length != newEntries.length) {
ICElementDelta delta = makePathEntryDelta(cproject, null, true); ICElementDelta delta = makePathEntryDelta(cproject, null, true);
if (delta != null) { if (delta != null) {
@ -1120,58 +1152,60 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} else { } else {
int kind = entry.getEntryKind(); int kind = entry.getEntryKind();
switch (kind) { switch (kind) {
case IPathEntry.CDT_SOURCE: { case IPathEntry.CDT_SOURCE: {
ISourceEntry source = (ISourceEntry)entry; ISourceEntry source = (ISourceEntry) entry;
IPath path = source.getPath(); IPath path = source.getPath();
celement = CoreModel.getDefault().create(path); celement = CoreModel.getDefault().create(path);
flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_SOURCE : ICElementDelta.F_ADDED_PATHENTRY_SOURCE; flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_SOURCE
break; : ICElementDelta.F_ADDED_PATHENTRY_SOURCE;
} break;
case IPathEntry.CDT_LIBRARY: { }
celement = cproject; case IPathEntry.CDT_LIBRARY: {
flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_LIBRARY : ICElementDelta.F_ADDED_PATHENTRY_LIBRARY; celement = cproject;
break; flag = (removed) ? ICElementDelta.F_REMOVED_PATHENTRY_LIBRARY
} : ICElementDelta.F_ADDED_PATHENTRY_LIBRARY;
case IPathEntry.CDT_PROJECT: { break;
//IProjectEntry pentry = (IProjectEntry) entry; }
celement = cproject; case IPathEntry.CDT_PROJECT: {
flag = ICElementDelta.F_CHANGED_PATHENTRY_PROJECT; // IProjectEntry pentry = (IProjectEntry) entry;
break; celement = cproject;
} flag = ICElementDelta.F_CHANGED_PATHENTRY_PROJECT;
case IPathEntry.CDT_INCLUDE: { break;
IIncludeEntry include = (IIncludeEntry)entry; }
IPath path = include.getPath(); case IPathEntry.CDT_INCLUDE: {
celement = CoreModel.getDefault().create(path); IIncludeEntry include = (IIncludeEntry) entry;
flag = ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE; IPath path = include.getPath();
break; celement = CoreModel.getDefault().create(path);
} flag = ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE;
case IPathEntry.CDT_INCLUDE_FILE: { break;
IIncludeFileEntry includeFile = (IIncludeFileEntry)entry; }
IPath path = includeFile.getPath(); case IPathEntry.CDT_INCLUDE_FILE: {
celement = CoreModel.getDefault().create(path); IIncludeFileEntry includeFile = (IIncludeFileEntry) entry;
flag = ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE; IPath path = includeFile.getPath();
break; celement = CoreModel.getDefault().create(path);
} flag = ICElementDelta.F_CHANGED_PATHENTRY_INCLUDE;
case IPathEntry.CDT_MACRO: { break;
IMacroEntry macro = (IMacroEntry)entry; }
IPath path = macro.getPath(); case IPathEntry.CDT_MACRO: {
celement = CoreModel.getDefault().create(path); IMacroEntry macro = (IMacroEntry) entry;
flag = ICElementDelta.F_CHANGED_PATHENTRY_MACRO; IPath path = macro.getPath();
break; celement = CoreModel.getDefault().create(path);
} flag = ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
case IPathEntry.CDT_MACRO_FILE: { break;
IMacroFileEntry macro = (IMacroFileEntry)entry; }
IPath path = macro.getPath(); case IPathEntry.CDT_MACRO_FILE: {
celement = CoreModel.getDefault().create(path); IMacroFileEntry macro = (IMacroFileEntry) entry;
flag = ICElementDelta.F_CHANGED_PATHENTRY_MACRO; IPath path = macro.getPath();
break; celement = CoreModel.getDefault().create(path);
} flag = ICElementDelta.F_CHANGED_PATHENTRY_MACRO;
case IPathEntry.CDT_CONTAINER: { break;
//IContainerEntry container = (IContainerEntry) entry; }
//celement = cproject; case IPathEntry.CDT_CONTAINER: {
//SHOULD NOT BE HERE Container are resolved. // IContainerEntry container = (IContainerEntry) entry;
break; // celement = cproject;
} // SHOULD NOT BE HERE Container are resolved.
break;
}
} }
} }
if (celement == null) { if (celement == null) {
@ -1222,16 +1256,16 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
} }
public IPathEntryStore getPathEntryStore(IProject project, boolean create) throws CoreException { public IPathEntryStore getPathEntryStore(IProject project, boolean create) throws CoreException {
synchronized (storeMap){ synchronized (storeMap) {
IPathEntryStore store = storeMap.get(project); IPathEntryStore store = storeMap.get(project);
if (store == null) { if (store == null) {
if (create == true){ if (create == true) {
store = createPathEntryStore(project); store = createPathEntryStore(project);
storeMap.put(project, store); storeMap.put(project, store);
store.addPathEntryStoreListener(this); store.addPathEntryStoreListener(this);
} }
} else if (store instanceof AbstractCExtensionProxy){ } else if (store instanceof AbstractCExtensionProxy) {
((AbstractCExtensionProxy)store).updateProject(project); ((AbstractCExtensionProxy) store).updateProject(project);
} }
return store; return store;
} }
@ -1239,45 +1273,50 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
public IPathEntryStore createPathEntryStore(IProject project) throws CoreException { public IPathEntryStore createPathEntryStore(IProject project) throws CoreException {
return new PathEntryStoreProxy(project); return new PathEntryStoreProxy(project);
// IPathEntryStore store = null; // IPathEntryStore store = null;
// if (project != null) { // if (project != null) {
// try { // try {
// ICDescriptor cdesc = CCorePlugin.getDefault().getCProjectDescription(project, false); // ICDescriptor cdesc =
// if (cdesc != null) { // CCorePlugin.getDefault().getCProjectDescription(project, false);
// ICExtensionReference[] cextensions = cdesc.get(PATHENTRY_STORE_UNIQ_ID, true); // if (cdesc != null) {
// if (cextensions.length > 0) { // ICExtensionReference[] cextensions =
// for (int i = 0; i < cextensions.length; i++) { // cdesc.get(PATHENTRY_STORE_UNIQ_ID, true);
// try { // if (cextensions.length > 0) {
// store = (IPathEntryStore)cextensions[i].createExtension(); // for (int i = 0; i < cextensions.length; i++) {
// break; // try {
// } catch (ClassCastException e) { // store = (IPathEntryStore)cextensions[i].createExtension();
// // // break;
// CCorePlugin.log(e); // } catch (ClassCastException e) {
// } // //
// } // CCorePlugin.log(e);
// } // }
// } // }
// } catch (CoreException e) { // }
// // ignore since we fall back to a default.... // }
// } // } catch (CoreException e) {
// } // // ignore since we fall back to a default....
// if (store == null) { // }
// store = createDefaultStore(project); // }
// } // if (store == null) {
// return store; // store = createDefaultStore(project);
// }
// return store;
} }
// private IPathEntryStore createDefaultStore(IProject project){ // private IPathEntryStore createDefaultStore(IProject project){
// if (CProjectDescriptionManager.getInstance().isNewStyleIndexCfg(project)){ // if
// return new ConfigBasedPathEntryStore(project); // (CProjectDescriptionManager.getInstance().isNewStyleIndexCfg(project)){
// } // return new ConfigBasedPathEntryStore(project);
// return new DefaultPathEntryStore(project); // }
// } // return new DefaultPathEntryStore(project);
// }
/* /*
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.eclipse.cdt.core.resources.IPathEntryStoreListener#pathEntryStoreChanged(org.eclipse.cdt.core.resources.PathEntryChangedEvent) * @see org.eclipse.cdt.core.resources.IPathEntryStoreListener#
* pathEntryStoreChanged(org.eclipse.cdt.core.resources.
* PathEntryChangedEvent)
*/ */
@Override @Override
public void pathEntryStoreChanged(PathEntryStoreChangedEvent event) { public void pathEntryStoreChanged(PathEntryStoreChangedEvent event) {
@ -1318,11 +1357,13 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
if (entries != null) { if (entries != null) {
IProject project = project2.getProject(); IProject project = project2.getProject();
try { try {
IMarker[] markers = project.findMarkers(ICModelMarker.PATHENTRY_PROBLEM_MARKER, false, IResource.DEPTH_ZERO); IMarker[] markers = project.findMarkers(ICModelMarker.PATHENTRY_PROBLEM_MARKER,
false, IResource.DEPTH_ZERO);
if (markers != null && markers.length > 0) { if (markers != null && markers.length > 0) {
ArrayList<ICModelStatus> problemList = new ArrayList<>(); ArrayList<ICModelStatus> problemList = new ArrayList<>();
for (IPathEntry entry : entries) { for (IPathEntry entry : entries) {
ICModelStatus status = PathEntryUtil.validatePathEntry(project2, entry, true, false); ICModelStatus status = PathEntryUtil.validatePathEntry(project2, entry,
true, false);
if (!status.isOK()) { if (!status.isOK()) {
problemList.add(status); problemList.add(status);
} }
@ -1350,7 +1391,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
// Handle open, closing and removing of projects // Handle open, closing and removing of projects
if (type == ICElement.C_PROJECT) { if (type == ICElement.C_PROJECT) {
ICProject cproject = (ICProject)element; ICProject cproject = (ICProject) element;
if ((kind == ICElementDelta.REMOVED || kind == ICElementDelta.ADDED)) { if ((kind == ICElementDelta.REMOVED || kind == ICElementDelta.ADDED)) {
if (kind == ICElementDelta.REMOVED) { if (kind == ICElementDelta.REMOVED) {
IProject project = cproject.getProject(); IProject project = cproject.getProject();
@ -1378,10 +1419,12 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return false; return false;
} }
if (kind == ICElementDelta.ADDED || kind == ICElementDelta.REMOVED) { if (kind == ICElementDelta.ADDED || kind == ICElementDelta.REMOVED) {
// If the element path maps to the some IPathEntry we need to remove that entry // If the element path maps to the some IPathEntry we need to remove
// but I'm not sure of the side effects so lets just do this for the ISourceEntry type // that entry
// but I'm not sure of the side effects so lets just do this for the
// ISourceEntry type
if (element instanceof ISourceRoot) { if (element instanceof ISourceRoot) {
ISourceRoot sourceRoot = (ISourceRoot)element; ISourceRoot sourceRoot = (ISourceRoot) element;
if (kind == ICElementDelta.REMOVED) { if (kind == ICElementDelta.REMOVED) {
updatePathEntryFromDeleteSource(sourceRoot); updatePathEntryFromDeleteSource(sourceRoot);
} }
@ -1403,6 +1446,7 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
/** /**
* The source root been deleted update the path entries * The source root been deleted update the path entries
*
* @param sourceRoot * @param sourceRoot
* @throws CModelException * @throws CModelException
*/ */
@ -1429,7 +1473,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
Job updatePathEntry = new WorkspaceJob("PathEntry Update source roots") { //$NON-NLS-1$ Job updatePathEntry = new WorkspaceJob("PathEntry Update source roots") { //$NON-NLS-1$
@Override @Override
public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException { public IStatus runInWorkspace(IProgressMonitor monitor) throws CoreException {
// If the path which triggered this change exists when we run this job then // If the path which triggered this change exists when we
// run this job then
// nothing to do. // nothing to do.
if (sourceRoot.getResource() == null || !sourceRoot.getResource().exists()) if (sourceRoot.getResource() == null || !sourceRoot.getResource().exists())
setRawPathEntries(cproject, finalEntries, monitor); setRawPathEntries(cproject, finalEntries, monitor);
@ -1447,8 +1492,8 @@ public class PathEntryManager implements IPathEntryStoreListener, IElementChange
return PathEntryUtil.validatePathEntry(cProject, entries); return PathEntryUtil.validatePathEntry(cProject, entries);
} }
public ICModelStatus validatePathEntry(ICProject cProject, IPathEntry entry, boolean checkSourceAttachment, public ICModelStatus validatePathEntry(ICProject cProject, IPathEntry entry,
boolean recurseInContainers) { boolean checkSourceAttachment, boolean recurseInContainers) {
return PathEntryUtil.validatePathEntry(cProject, entry, checkSourceAttachment, recurseInContainers); return PathEntryUtil.validatePathEntry(cProject, entry, checkSourceAttachment, recurseInContainers);
} }
} }

View file

@ -9,8 +9,6 @@ Require-Bundle: org.eclipse.core.runtime,
org.eclipse.core.resources, org.eclipse.core.resources,
org.eclipse.debug.core, org.eclipse.debug.core,
org.eclipse.cdt.core, org.eclipse.cdt.core,
org.eclipse.cdt.managedbuilder.core,
org.eclipse.cdt.managedbuilder.gnu.ui,
org.eclipse.launchbar.core, org.eclipse.launchbar.core,
org.eclipse.remote.core;bundle-version="2.0.0", org.eclipse.remote.core;bundle-version="2.0.0",
org.eclipse.cdt.native.serial;bundle-version="1.0.0", org.eclipse.cdt.native.serial;bundle-version="1.0.0",
@ -25,5 +23,6 @@ Bundle-ClassPath: libs/freemarker-2.3.22.jar,
. .
Export-Package: org.eclipse.cdt.arduino.core.internal;x-friends:="org.eclipse.cdt.arduino.ui", 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.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.build;x-friends:="org.eclipse.cdt.arduino.ui",
org.eclipse.cdt.arduino.core.internal.console;x-friends:="org.eclipse.cdt.arduino.ui"
Bundle-Localization: plugin Bundle-Localization: plugin

View file

@ -10,3 +10,4 @@
############################################################################### ###############################################################################
pluginName=Arduino C++ Core pluginName=Arduino C++ Core
providerName=Eclipse CDT providerName=Eclipse CDT
ArduinoBuilder.name=Arduino Builder

View file

@ -2,95 +2,6 @@
<?eclipse version="3.4"?> <?eclipse version="3.4"?>
<plugin> <plugin>
<extension-point id="consoleService" name="Arduino Launch Console Service" schema="schema/consoleService.exsd"/> <extension-point id="consoleService" name="Arduino Launch Console Service" schema="schema/consoleService.exsd"/>
<extension
point="org.eclipse.cdt.managedbuilder.core.buildDefinitions">
<managedBuildRevision
fileVersion="4.0.0">
</managedBuildRevision>
<toolChain
archList="all"
configurationEnvironmentSupplier="org.eclipse.cdt.arduino.core.internal.EnvVarSupplier"
id="org.eclipse.cdt.arduino.toolChain.avr"
isAbstract="false"
languageSettingsProviders="org.eclipse.cdt.arduino.avr.builtins;org.eclipse.cdt.arduino.avr.outputParser"
name="Arduino AVR C++"
osList="all"
supportsManagedBuild="false">
<targetPlatform
id="org.eclipse.cdt.arduino.targetPlatform"
isAbstract="false"
name="Arduino">
</targetPlatform>
<builder
autoBuildTarget="all"
buildRunner="org.eclipse.cdt.managedbuilder.core.ExternalBuildRunner"
cleanBuildTarget="clean"
command="make"
commandLauncher="org.eclipse.cdt.core.CommandLauncher"
id="org.eclipse.cdt.arduino.builder.make"
incrementalBuildTarget="all"
isAbstract="false"
isVariableCaseSensitive="false"
name="Arduino Make">
</builder>
<tool
command="avr-g++"
id="org.eclipse.cdt.arduino.tool.avr.compiler"
isAbstract="false"
name="Arduino AVR C++ Compiler"
natureFilter="ccnature"
superClass="cdt.managedbuild.tool.gnu.cpp.compiler.base">
</tool>
<option
category="org.eclipse.cdt.arduino.optionCategory.board"
id="org.eclipse.cdt.arduino.option.board"
isAbstract="false"
name="Board Type"
resourceFilter="all"
valueType="string">
</option>
<option
category="org.eclipse.cdt.arduino.optionCategory.board"
id="org.eclipse.cdt.arduino.option.platform"
isAbstract="false"
name="Board Platform"
resourceFilter="all"
valueType="string">
</option>
<option
category="org.eclipse.cdt.arduino.optionCategory.board"
id="org.eclipse.cdt.arduino.option.package"
isAbstract="false"
name="Board Package"
resourceFilter="all"
valueType="string">
</option>
<optionCategory
id="org.eclipse.cdt.arduino.optionCategory.board"
name="Board Type">
</optionCategory>
</toolChain>
</extension>
<extension
point="org.eclipse.cdt.core.LanguageSettingsProvider">
<provider
class="org.eclipse.cdt.arduino.core.internal.AvrLanguageSettingsProvider"
id="org.eclipse.cdt.arduino.avr.builtins"
name="Arduino AVR Compiler Built-ins"
parameter="${COMMAND} ${FLAGS} -E -P -v -dD &quot;${INPUTS}&quot;"
prefer-non-shared="true">
<language-scope
id="org.eclipse.cdt.core.g++">
</language-scope>
</provider>
<provider
class="org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuildCommandParser"
id="org.eclipse.cdt.arduino.avr.outputParser"
name="Arduino AVR Built Output Parser"
parameter="(avr-gcc)|(avr-g\+\+)"
prefer-non-shared="true">
</provider>
</extension>
<extension <extension
point="org.eclipse.debug.core.launchConfigurationTypes"> point="org.eclipse.debug.core.launchConfigurationTypes">
<launchConfigurationType <launchConfigurationType
@ -163,15 +74,39 @@
class="org.eclipse.cdt.arduino.core.internal.ArduinoProjectNature"> class="org.eclipse.cdt.arduino.core.internal.ArduinoProjectNature">
</run> </run>
</runtime> </runtime>
<builder
id="org.eclipse.cdt.arduino.core.arduinoBuilder">
</builder>
</extension> </extension>
<extension <extension
id="arduinoBuilder" id="arduinoBuilder"
name="%ArduinoBuilder.name"
point="org.eclipse.core.resources.builders"> point="org.eclipse.core.resources.builders">
<builder <builder
hasNature="true"> callOnEmptyDelta="true"
hasNature="true"
isConfigurable="true"
supportsConfigurations="true">
<run <run
class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder"> class="org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder">
</run> </run>
</builder> </builder>
</extension> </extension>
<extension
point="org.eclipse.cdt.core.ScannerInfoProvider2">
<provider
builder="org.eclipse.cdt.arduino.core.arduinoBuilder"
class="org.eclipse.cdt.arduino.core.ArduinoScannerInfoProvider">
</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>
</plugin> </plugin>

View file

@ -0,0 +1,37 @@
package org.eclipse.cdt.arduino.core;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.cdt.core.parser.ExtendedScannerInfo;
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.IResource;
/**
* Responsible for collecting scanner info on Arduino Projects.
*/
public class ArduinoScannerInfoProvider implements IScannerInfoProvider {
@Override
public IScannerInfo getScannerInformation(IResource resource) {
Map<String, String> symbols = new HashMap<>();
String[] includePath = { "/Users/dschaefer/.arduinocdt/hardware/arduino/avr/1.6.7/cores/arduino" };
ExtendedScannerInfo scannerInfo = new ExtendedScannerInfo(symbols, includePath);
return scannerInfo;
}
@Override
public void subscribe(IResource resource, IScannerInfoChangeListener listener) {
// TODO Auto-generated method stub
}
@Override
public void unsubscribe(IResource resource, IScannerInfoChangeListener listener) {
// TODO Auto-generated method stub
}
}

View file

@ -10,12 +10,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal; package org.eclipse.cdt.arduino.core.internal;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder; import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent;
import org.eclipse.cdt.core.settings.model.ICProjectDescriptionListener;
import org.eclipse.core.runtime.CoreException; 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.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Plugin; import org.eclipse.core.runtime.Plugin;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
@ -47,14 +47,6 @@ public class Activator extends Plugin {
public void start(BundleContext bundleContext) throws Exception { public void start(BundleContext bundleContext) throws Exception {
plugin = this; plugin = this;
// register listener for build config changes
CoreModel.getDefault().addCProjectDescriptionListener(new ICProjectDescriptionListener() {
@Override
public void handleEvent(CProjectDescriptionEvent event) {
ArduinoBuilder.handleProjectDescEvent(event);
}
}, CProjectDescriptionEvent.APPLIED);
} }
public void stop(BundleContext bundleContext) throws Exception { public void stop(BundleContext bundleContext) throws Exception {
@ -67,4 +59,10 @@ public class Activator extends Plugin {
return ref != null ? context.getService(ref) : null; return ref != null ? context.getService(ref) : null;
} }
public static ArduinoConsoleService getConsoleService() throws CoreException {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getId(), "consoleService"); //$NON-NLS-1$
IExtension extension = point.getExtensions()[0]; // should only be one
return (ArduinoConsoleService) extension.getConfigurationElements()[0].createExecutableExtension("class"); //$NON-NLS-1$
}
} }

View file

@ -10,47 +10,27 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal; package org.eclipse.cdt.arduino.core.internal;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.Writer;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuildConfiguration;
import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder; import org.eclipse.cdt.arduino.core.internal.build.ArduinoBuilder;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection; import org.eclipse.cdt.core.CCProjectNature;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CProjectNature;
import org.eclipse.cdt.core.settings.model.ICProjectDescription; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedBuildInfo; import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
import org.eclipse.core.resources.ICommand; import org.eclipse.core.resources.ICommand;
import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectDescription; import org.eclipse.core.resources.IProjectDescription;
import org.eclipse.core.resources.IncrementalProjectBuilder; import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IProgressMonitor; 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 org.eclipse.core.runtime.jobs.Job;
import org.eclipse.remote.core.IRemoteConnection;
import org.eclipse.remote.core.IRemoteConnectionType;
import org.eclipse.remote.core.IRemoteServicesManager;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
@SuppressWarnings("restriction")
public class ArduinoProjectGenerator { public class ArduinoProjectGenerator {
private final IProject project; private final IProject project;
@ -61,100 +41,51 @@ public class ArduinoProjectGenerator {
} }
public void setupArduinoProject(IProgressMonitor monitor) throws CoreException { public void setupArduinoProject(IProgressMonitor monitor) throws CoreException {
// Add Arduino nature // Add natures to project: C, C++, Arduino
IProjectDescription projDesc = project.getDescription(); IProjectDescription projDesc = project.getDescription();
String[] oldIds = projDesc.getNatureIds(); String[] oldIds = projDesc.getNatureIds();
String[] newIds = new String[oldIds.length + 1]; String[] newIds = new String[oldIds.length + 3];
System.arraycopy(oldIds, 0, newIds, 0, oldIds.length); 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; newIds[newIds.length - 1] = ArduinoProjectNature.ID;
projDesc.setNatureIds(newIds); projDesc.setNatureIds(newIds);
// Add Arduino Builder // Add Arduino Builder
ICommand command = projDesc.newCommand(); ICommand command = projDesc.newCommand();
command.setBuilderName(ArduinoBuilder.ID); command.setBuilderName(ArduinoBuilder.ID);
command.setBuilding(IncrementalProjectBuilder.AUTO_BUILD, false);
projDesc.setBuildSpec(new ICommand[] { command }); projDesc.setBuildSpec(new ICommand[] { command });
// Create the default config
projDesc.setBuildConfigs(new String[] { "arduinoDefault" }); //$NON-NLS-1$
project.setDescription(projDesc, monitor); project.setDescription(projDesc, monitor);
// create the CDT natures and build setup // Test config
CCorePlugin.getDefault().createCDTProject(projDesc, project, monitor); IBuildConfiguration config = project.getBuildConfig("arduinoDefault"); //$NON-NLS-1$
ICProjectDescription cprojDesc = CCorePlugin.getDefault().createProjectDescription(project, false); ArduinoBuildConfiguration arduinoConfig = config.getAdapter(ArduinoBuildConfiguration.class);
ManagedBuildInfo info = ManagedBuildManager.createBuildInfo(project); // TODO for now assume Uno
ManagedProject mProj = new ManagedProject(cprojDesc); ArduinoBoard board = ArduinoBoardManager.instance.getBoard("Arduino Uno", "Arduino AVR Boards", "arduino"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
info.setManagedProject(mProj); arduinoConfig.setBoard(board);
// TODO make this a preference, the default board
String boardName = "Arduino Uno"; //$NON-NLS-1$
String platformName = "Arduino AVR Boards"; //$NON-NLS-1$
String packageName = "arduino"; //$NON-NLS-1$
IRemoteServicesManager remoteManager = Activator.getService(IRemoteServicesManager.class);
IRemoteConnectionType connectionType = remoteManager.getConnectionType(ArduinoRemoteConnection.TYPE_ID);
Collection<IRemoteConnection> connections = connectionType.getConnections();
if (!connections.isEmpty()) {
IRemoteConnection firstConnection = connections.iterator().next();
IArduinoRemoteConnection firstArduino = firstConnection.getService(IArduinoRemoteConnection.class);
boardName = firstArduino.getBoardName();
platformName = firstArduino.getPlatformName();
packageName = firstArduino.getPackageName();
}
ArduinoBoardManager.instance.createBuildConfiguration(cprojDesc, boardName, platformName, packageName);
CCorePlugin.getDefault().setProjectDescription(project, cprojDesc, true, monitor);
// Generate files // Generate files
try { ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
Configuration fmConfig = new Configuration(Configuration.VERSION_2_3_22); Map<String, Object> fmModel = new HashMap<>();
URL templateDirURL = FileLocator.find(Activator.getContext().getBundle(), new Path("/templates"), null); //$NON-NLS-1$ fmModel.put("projectName", project.getName()); //$NON-NLS-1$
fmConfig.setDirectoryForTemplateLoading(new File(FileLocator.toFileURL(templateDirURL).toURI()));
final Map<String, Object> fmModel = new HashMap<>(); templateGen.generateFile(fmModel, "Makefile", project.getFile("Makefile"), monitor); //$NON-NLS-1$ //$NON-NLS-2$
fmModel.put("projectName", project.getName()); //$NON-NLS-1$ templateGen.generateFile(fmModel, "arduino.mk", project.getFile("arduino.mk"), monitor); //$NON-NLS-1$ //$NON-NLS-2$
generateFile(fmModel, fmConfig.getTemplate("Makefile"), project.getFile("Makefile")); //$NON-NLS-1$ //$NON-NLS-2$ IFolder sourceFolder = project.getFolder("src"); //$NON-NLS-1$
generateFile(fmModel, fmConfig.getTemplate("arduino.mk"), project.getFile("arduino.mk")); //$NON-NLS-1$ //$NON-NLS-2$ if (!sourceFolder.exists()) {
sourceFolder.create(true, true, monitor);
sourceFile = project.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
generateFile(fmModel, fmConfig.getTemplate("arduino.cpp"), sourceFile); //$NON-NLS-1$
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
} catch (URISyntaxException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
} catch (TemplateException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
} }
IPathEntry[] entries = new IPathEntry[] { CoreModel.newOutputEntry(sourceFolder.getFullPath()) };
CoreModel.getDefault().create(project).setRawPathEntries(entries, monitor);
// Do the initial build sourceFile = sourceFolder.getFile(project.getName() + ".cpp"); //$NON-NLS-1$
project.build(IncrementalProjectBuilder.FULL_BUILD, monitor); templateGen.generateFile(fmModel, "arduino.cpp", sourceFile, monitor); //$NON-NLS-1$
}
private static void generateFile(Object model, Template template, final IFile outputFile)
throws TemplateException, IOException, CoreException {
final PipedInputStream in = new PipedInputStream();
PipedOutputStream out = new PipedOutputStream(in);
final Writer writer = new OutputStreamWriter(out);
Job job = new Job(Messages.ArduinoProjectGenerator_0) {
protected IStatus run(IProgressMonitor monitor) {
try {
outputFile.create(in, true, monitor);
} catch (CoreException e) {
return e.getStatus();
}
return Status.OK_STATUS;
}
};
job.setRule(outputFile.getProject());
job.schedule();
template.process(model, writer);
writer.close();
try {
job.join();
} catch (InterruptedException e) {
// TODO anything?
}
IStatus status = job.getResult();
if (!status.isOK())
throw new CoreException(status);
} }
public IFile getSourceFile() { public IFile getSourceFile() {

View file

@ -0,0 +1,58 @@
package org.eclipse.cdt.arduino.core.internal;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
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.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
public class ArduinoTemplateGenerator {
private final Configuration config;
public ArduinoTemplateGenerator() throws CoreException {
config = new Configuration(Configuration.VERSION_2_3_22);
URL templateDirURL = FileLocator.find(Activator.getContext().getBundle(), new Path("/templates"), null); //$NON-NLS-1$
try {
config.setDirectoryForTemplateLoading(new File(FileLocator.toFileURL(templateDirURL).toURI()));
} catch (IOException | URISyntaxException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Template configuration", e));
}
}
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));
}
}
}

View file

@ -1,72 +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;
import java.io.File;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.language.settings.providers.GCCBuiltinSpecsDetector;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.Platform;
public class AvrLanguageSettingsProvider extends GCCBuiltinSpecsDetector {
@Override
public String getToolchainId() {
return "org.eclipse.cdt.arduino.toolChain.avr"; //$NON-NLS-1$
}
@Override
protected String getToolOptions(String languageId) {
String opts = super.getToolOptions(languageId);
try {
IConfiguration config = ManagedBuildManager.getConfigurationForDescription(currentCfgDescription);
Board board = ArduinoBoardManager.instance.getBoard(config);
String mcu = board.getProperty("build.mcu"); //$NON-NLS-1$
if (mcu != null) {
opts += " -mmcu=" + mcu; //$NON-NLS-1$
}
} catch (CoreException e) {
Activator.getPlugin().getLog().log(e.getStatus());
}
return opts;
}
@Override
protected List<String> parseOptions(String line) {
if (Platform.getOS().equals(Platform.OS_WIN32)) {
if (line.startsWith(" /arduino/")) { //$NON-NLS-1$
// TODO
File full = new File(ArduinoPreferences.getArduinoHome().toFile(), line.trim());
return parseOptions(" " + full.getAbsolutePath()); //$NON-NLS-1$
}
}
return super.parseOptions(line);
}
@Override
public AvrLanguageSettingsProvider cloneShallow() throws CloneNotSupportedException {
return (AvrLanguageSettingsProvider) super.cloneShallow();
}
@Override
public AvrLanguageSettingsProvider clone() throws CloneNotSupportedException {
return (AvrLanguageSettingsProvider) super.clone();
}
}

View file

@ -1,118 +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;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.envvar.IBuildEnvironmentVariable;
import org.eclipse.cdt.managedbuilder.envvar.IConfigurationEnvironmentVariableSupplier;
import org.eclipse.cdt.managedbuilder.envvar.IEnvironmentVariableProvider;
import org.eclipse.core.runtime.Platform;
public class EnvVarSupplier implements IConfigurationEnvironmentVariableSupplier {
private EnvVar arduinoHome;
private EnvVar arduinoLibs;
private EnvVar path;
private static final String OUTPUT_DIR = "OUTPUT_DIR"; //$NON-NLS-1$
private static final class EnvVar implements IBuildEnvironmentVariable {
String name;
String value;
int operation = IBuildEnvironmentVariable.ENVVAR_REPLACE;
String delimiter = null;
@Override
public String getName() {
return name;
}
@Override
public String getValue() {
return value;
}
@Override
public int getOperation() {
return operation;
}
@Override
public String getDelimiter() {
return delimiter;
}
}
private String clean(String str) {
return str.replaceAll("\\\\", "/"); //$NON-NLS-1$ //$NON-NLS-2$
}
public EnvVarSupplier() {
arduinoHome = new EnvVar();
arduinoHome.name = "ARDUINO_HOME"; //$NON-NLS-1$
arduinoHome.value = clean(ArduinoPreferences.getArduinoHome().toString());
arduinoLibs = new EnvVar();
arduinoLibs.name = "ARDUINO_USER_LIBS"; //$NON-NLS-1$
arduinoLibs.value = clean(System.getProperty("user.home") + "/Documents/Arduino/libraries"); //$NON-NLS-1$ //$NON-NLS-2$
String avrDir = ArduinoPreferences.getArduinoHome().toString() + "/hardware/tools/avr/bin"; //$NON-NLS-1$
String installDir = Platform.getInstallLocation().getURL().getPath();
path = new EnvVar();
path.name = "PATH"; //$NON-NLS-1$
path.value = avrDir + File.pathSeparator + installDir;
path.operation = IBuildEnvironmentVariable.ENVVAR_PREPEND;
path.delimiter = File.pathSeparator;
}
private IBuildEnvironmentVariable getOutputDir(IConfiguration configuration) {
EnvVar outputDir = new EnvVar();
outputDir.name = OUTPUT_DIR;
outputDir.value = "build/" + configuration.getName(); //$NON-NLS-1$
return outputDir;
}
@Override
public IBuildEnvironmentVariable getVariable(String variableName, IConfiguration configuration,
IEnvironmentVariableProvider provider) {
if (variableName.equals(path.name)) {
return path;
} else if (variableName.equals(arduinoHome.name)) {
return arduinoHome;
} else if (variableName.equals(arduinoLibs.name)) {
return arduinoLibs;
} else if (variableName.equals(OUTPUT_DIR)) {
return getOutputDir(configuration);
}
return null;
}
@Override
public IBuildEnvironmentVariable[] getVariables(IConfiguration configuration,
IEnvironmentVariableProvider provider) {
List<IBuildEnvironmentVariable> vars = new ArrayList<>();
vars.add(path);
vars.add(arduinoHome);
vars.add(arduinoLibs);
if (configuration != null) {
vars.add(getOutputDir(configuration));
}
return vars.toArray(new IBuildEnvironmentVariable[vars.size()]);
}
}

View file

@ -68,7 +68,7 @@ public class HierarchicalProperties {
HierarchicalProperties child = children.get(key); HierarchicalProperties child = children.get(key);
if (child == null) { if (child == null) {
child = new HierarchicalProperties(); child = new HierarchicalProperties();
children.put(qualifiedKey, child); children.put(key, child);
} }
String childKey = qualifiedKey.substring(i + 1); String childKey = qualifiedKey.substring(i + 1);
child.putProperty(childKey, value); child.putProperty(childKey, value);
@ -133,4 +133,26 @@ public class HierarchicalProperties {
} }
} }
public Properties flatten() {
Properties properties = new Properties();
flatten(null, this, properties);
return properties;
}
private static void flatten(String prefix, HierarchicalProperties tree, Properties props) {
if (tree.getValue() != null && prefix != null) {
props.put(prefix, tree.getValue());
}
if (tree.getChildren() != null) {
for (Map.Entry<String, HierarchicalProperties> entry : tree.getChildren().entrySet()) {
String childPrefix = entry.getKey();
if (prefix != null) {
childPrefix = prefix + "." + childPrefix; //$NON-NLS-1$
}
flatten(childPrefix, entry.getValue(), props);
}
}
}
} }

View file

@ -7,23 +7,25 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board; package org.eclipse.cdt.arduino.core.internal.board;
import java.util.Properties;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties; import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
public class Board { public class ArduinoBoard {
private String name; private String name;
private String id; private String id;
private Platform platform; private ArduinoPlatform platform;
private HierarchicalProperties properties; private HierarchicalProperties properties;
public Board() { public ArduinoBoard() {
} }
public Board(HierarchicalProperties properties) { public ArduinoBoard(String id, HierarchicalProperties properties) {
this.properties = properties; this.properties = properties;
this.id = this.properties.getValue(); this.id = id;
this.name = this.properties.getChild("name").getValue(); //$NON-NLS-1$ this.name = this.properties.getChild("name").getValue(); //$NON-NLS-1$
} }
@ -35,11 +37,11 @@ public class Board {
return id; return id;
} }
public Platform getPlatform() { public ArduinoPlatform getPlatform() {
return platform; return platform;
} }
Board setOwners(Platform platform) { ArduinoBoard setOwners(ArduinoPlatform platform) {
this.platform = platform; this.platform = platform;
return this; return this;
} }
@ -48,12 +50,8 @@ public class Board {
return properties.getProperty(key); return properties.getProperty(key);
} }
public String getPlatformId() { public Properties getBoardProperties() {
return platform.getArchitecture(); return properties.flatten();
}
public String getPackageId() {
return platform.getPackage().getName();
} }
} }

View file

@ -10,32 +10,28 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board; package org.eclipse.cdt.arduino.core.internal.board;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader; import java.io.FileReader;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.StandardCopyOption; import java.nio.file.StandardCopyOption;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.apache.http.HttpEntity; import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.http.client.methods.CloseableHttpResponse; import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.http.client.methods.HttpGet; import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.http.impl.client.CloseableHttpClient; import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.http.impl.client.HttpClients; import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences; import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.Messages; import org.eclipse.cdt.arduino.core.internal.Messages;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.core.settings.model.extension.CConfigurationData;
import org.eclipse.cdt.managedbuilder.core.BuildException;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.IOption;
import org.eclipse.cdt.managedbuilder.core.IToolChain;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.cdt.managedbuilder.internal.core.ManagedProject;
import org.eclipse.cdt.managedbuilder.internal.core.ToolChain;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -62,21 +58,10 @@ public class ArduinoBoardManager {
public ArduinoBoardManager() { public ArduinoBoardManager() {
new Job(Messages.ArduinoBoardManager_0) { new Job(Messages.ArduinoBoardManager_0) {
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
try (CloseableHttpClient client = HttpClients.createDefault()) { try {
HttpGet get = new HttpGet("http://downloads.arduino.cc/packages/package_index.json"); //$NON-NLS-1$ URL url = new URL("http://downloads.arduino.cc/packages/package_index.json"); //$NON-NLS-1$
try (CloseableHttpResponse response = client.execute(get)) { Files.createDirectories(packageIndexPath.getParent());
if (response.getStatusLine().getStatusCode() >= 400) { Files.copy(url.openStream(), packageIndexPath, StandardCopyOption.REPLACE_EXISTING);
return new Status(IStatus.ERROR, Activator.getId(),
response.getStatusLine().getReasonPhrase());
} else {
HttpEntity entity = response.getEntity();
if (entity == null) {
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoBoardManager_1);
}
Files.createDirectories(packageIndexPath.getParent());
Files.copy(entity.getContent(), packageIndexPath, StandardCopyOption.REPLACE_EXISTING);
}
}
} catch (IOException e) { } catch (IOException e) {
return new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e); return new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e);
} }
@ -85,72 +70,99 @@ public class ArduinoBoardManager {
}.schedule(); }.schedule();
} }
public PackageIndex getPackageIndex() throws IOException { public PackageIndex getPackageIndex() throws CoreException {
if (packageIndex == null) { if (packageIndex == null) {
try (FileReader reader = new FileReader(packageIndexPath.toFile())) { try (FileReader reader = new FileReader(packageIndexPath.toFile())) {
packageIndex = new Gson().fromJson(reader, PackageIndex.class); packageIndex = new Gson().fromJson(reader, PackageIndex.class);
packageIndex.setOwners(this); packageIndex.setOwners(this);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Reading package index", e));
} }
} }
return packageIndex; return packageIndex;
} }
public ICConfigurationDescription createBuildConfiguration(ICProjectDescription projDesc, String boardId, public ArduinoBoard getBoard(String boardName, String platformName, String packageName) throws CoreException {
String platformId, String packageId) throws CoreException { return getPackageIndex().getPackage(packageName).getPlatform(platformName).getBoard(boardName);
Board board = packageIndex.getPackage(packageId).getPlatform(platformId).getBoard(boardId);
ManagedProject managedProject = new ManagedProject(projDesc);
// TODO find toolchain based on package (os), platform (arch).
String configId = ManagedBuildManager.calculateChildId(ArduinoBoardManager.AVR_TOOLCHAIN_ID, null);
IToolChain avrToolChain = ManagedBuildManager.getExtensionToolChain(ArduinoBoardManager.AVR_TOOLCHAIN_ID);
org.eclipse.cdt.managedbuilder.internal.core.Configuration newConfig = new org.eclipse.cdt.managedbuilder.internal.core.Configuration(
managedProject, (ToolChain) avrToolChain, configId, board.getName());
IToolChain newToolChain = newConfig.getToolChain();
IOption boardOption = newToolChain.getOptionBySuperClassId(BOARD_OPTION_ID);
ManagedBuildManager.setOption(newConfig, newToolChain, boardOption, boardId);
IOption platformOption = newToolChain.getOptionBySuperClassId(PLATFORM_OPTION_ID);
ManagedBuildManager.setOption(newConfig, newToolChain, platformOption, platformId);
IOption packageOption = newToolChain.getOptionBySuperClassId(PACKAGE_OPTION_ID);
ManagedBuildManager.setOption(newConfig, newToolChain, packageOption, packageId);
CConfigurationData data = newConfig.getConfigurationData();
return projDesc.createConfiguration(ManagedBuildManager.CFG_DATA_PROVIDER_ID, data);
} }
public Board getBoard(String boardName, String platformName, String packageName) throws CoreException { public List<ArduinoBoard> getBoards() throws CoreException {
return packageIndex.getPackage(packageName).getPlatform(platformName).getBoard(boardName); List<ArduinoBoard> boards = new ArrayList<>();
} for (ArduinoPackage pkg : packageIndex.getPackages()) {
for (ArduinoPlatform platform : pkg.getPlatforms()) {
public Board getBoard(IConfiguration configuration) throws CoreException {
try {
IToolChain toolChain = configuration.getToolChain();
IOption boardOption = toolChain.getOptionBySuperClassId(BOARD_OPTION_ID);
String boardName = boardOption.getStringValue();
IOption platformOption = toolChain.getOptionBySuperClassId(PLATFORM_OPTION_ID);
String platformName = platformOption.getStringValue();
IOption packageOption = toolChain.getOptionBySuperClassId(PACKAGE_OPTION_ID);
String packageName = packageOption.getStringValue();
return getBoard(boardName, platformName, packageName);
} catch (BuildException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), e.getLocalizedMessage(), e));
}
}
public List<Board> getBoards() throws CoreException {
List<Board> boards = new ArrayList<>();
for (BoardPackage pkg : packageIndex.getPackages()) {
for (Platform platform : pkg.getPlatforms()) {
boards.addAll(platform.getBoards()); boards.addAll(platform.getBoards());
} }
} }
return boards; return boards;
} }
public Tool getTool(String packageName, String toolName, String version) { public ArduinoTool getTool(String packageName, String toolName, String version) {
BoardPackage pkg = packageIndex.getPackage(packageName); ArduinoPackage pkg = packageIndex.getPackage(packageName);
return pkg != null ? pkg.getTool(toolName, version) : null; return pkg != null ? pkg.getTool(toolName, version) : null;
} }
public static IStatus downloadAndInstall(String url, String archiveFileName, Path installPath,
IProgressMonitor monitor) {
try {
URL dl = new URL(url);
Path dlDir = ArduinoPreferences.getArduinoHome().resolve("downloads");
Files.createDirectories(dlDir);
Path archivePath = dlDir.resolve(archiveFileName);
Files.copy(dl.openStream(), archivePath, StandardCopyOption.REPLACE_EXISTING);
// extract
ArchiveInputStream archiveIn = null;
try {
String compressor = null;
String archiver = null;
if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.BZIP2;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$
compressor = CompressorStreamFactory.GZIP;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.XZ;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$
archiver = ArchiveStreamFactory.ZIP;
}
InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile()));
if (compressor != null) {
in = new CompressorStreamFactory().createCompressorInputStream(compressor, in);
}
archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in);
for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}
// TODO check for soft links in tar files.
Path entryPath = installPath.resolve(entry.getName());
Files.createDirectories(entryPath.getParent());
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
} finally {
if (archiveIn != null) {
archiveIn.close();
}
}
// Fix up directory
File[] children = installPath.toFile().listFiles();
if (children.length == 1 && children[0].isDirectory()) {
// make that directory the install path
Path childPath = children[0].toPath();
Path tmpPath = installPath.getParent().resolve("_t"); //$NON-NLS-1$
Files.move(childPath, tmpPath);
Files.delete(installPath);
Files.move(tmpPath, installPath);
}
return Status.OK_STATUS;
} catch (IOException | CompressorException | ArchiveException e) {
return new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e);
}
}
} }

View file

@ -7,7 +7,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board; package org.eclipse.cdt.arduino.core.internal.board;
public class Help { public class ArduinoHelp {
private String online; private String online;

View file

@ -15,22 +15,25 @@ import java.util.Map;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
public class BoardPackage { public class ArduinoPackage {
private String name; private String name;
private String maintainer; private String maintainer;
private String websiteURL; private String websiteURL;
private String email; private String email;
private Help help; private ArduinoHelp help;
private List<Platform> platforms; private List<ArduinoPlatform> platforms;
private List<Tool> tools; private List<ArduinoTool> tools;
private transient ArduinoBoardManager manager; private transient ArduinoBoardManager manager;
void setOwners(ArduinoBoardManager manager) { void setOwner(ArduinoBoardManager manager) {
this.manager = manager; this.manager = manager;
for (Platform platform : platforms) { for (ArduinoPlatform platform : platforms) {
platform.setOwners(this); platform.setOwner(this);
}
for (ArduinoTool tool : tools) {
tool.setOwner(this);
} }
} }
@ -54,11 +57,11 @@ public class BoardPackage {
return email; return email;
} }
public Help getHelp() { public ArduinoHelp getHelp() {
return help; return help;
} }
public Collection<Platform> getPlatforms() { public Collection<ArduinoPlatform> getPlatforms() {
return Collections.unmodifiableCollection(platforms); return Collections.unmodifiableCollection(platforms);
} }
@ -67,10 +70,10 @@ public class BoardPackage {
* *
* @return latest platforms * @return latest platforms
*/ */
public Collection<Platform> getLatestPlatforms() { public Collection<ArduinoPlatform> getLatestPlatforms() {
Map<String, Platform> platformMap = new HashMap<>(); Map<String, ArduinoPlatform> platformMap = new HashMap<>();
for (Platform platform : platforms) { for (ArduinoPlatform platform : platforms) {
Platform p = platformMap.get(platform.getName()); ArduinoPlatform p = platformMap.get(platform.getName());
if (p == null || compareVersions(platform.getVersion(), p.getVersion()) > 0) { if (p == null || compareVersions(platform.getVersion(), p.getVersion()) > 0) {
platformMap.put(platform.getName(), platform); platformMap.put(platform.getName(), platform);
} }
@ -124,22 +127,30 @@ public class BoardPackage {
return 0; return 0;
} }
public Platform getPlatform(String architecture) { public ArduinoPlatform getPlatform(String name) {
for (Platform platform : platforms) { ArduinoPlatform foundPlatform = null;
if (platform.getArchitecture().equals(architecture)) { for (ArduinoPlatform platform : platforms) {
return platform; if (platform.getName().equals(name)) {
if (foundPlatform == null) {
foundPlatform = platform;
} else {
if (platform.isInstalled()
&& compareVersions(platform.getVersion(), foundPlatform.getVersion()) > 0) {
foundPlatform = platform;
}
}
} }
} }
return null; return foundPlatform;
} }
public List<Tool> getTools() { public List<ArduinoTool> getTools() {
return tools; return tools;
} }
public Tool getTool(String toolName, String version) { public ArduinoTool getTool(String toolName, String version) {
for (Tool tool : tools) { for (ArduinoTool tool : tools) {
if (tool.getName().equals(toolName) && tool.getName().equals(version)) { if (tool.getName().equals(toolName) && tool.getVersion().equals(version)) {
return tool; return tool;
} }
} }
@ -150,4 +161,17 @@ public class BoardPackage {
} }
@Override
public boolean equals(Object obj) {
if (obj instanceof ArduinoPackage) {
return ((ArduinoPackage) obj).getName().equals(name);
}
return super.equals(obj);
}
@Override
public int hashCode() {
return name.hashCode();
}
} }

View file

@ -0,0 +1,176 @@
/*******************************************************************************
* 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.board;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Status;
public class ArduinoPlatform {
private String name;
private String architecture;
private String version;
private String category;
private String url;
private String archiveFileName;
private String checksum;
private String size;
private List<ArduinoBoard> boards;
private List<ToolDependency> toolsDependencies;
private transient ArduinoPackage pkg;
private transient HierarchicalProperties boardsFile;
void setOwner(ArduinoPackage pkg) {
this.pkg = pkg;
for (ArduinoBoard board : boards) {
board.setOwners(this);
}
for (ToolDependency toolDep : toolsDependencies) {
toolDep.setOwner(this);
}
}
public ArduinoPackage getPackage() {
return pkg;
}
public String getName() {
return name;
}
public String getArchitecture() {
return architecture;
}
public String getVersion() {
return version;
}
public String getCategory() {
return category;
}
public String getUrl() {
return url;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
public List<ArduinoBoard> getBoards() throws CoreException {
if (isInstalled() && boardsFile == null) {
Properties boardProps = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
boardProps.load(reader);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading boards.txt", e));
}
boardsFile = new HierarchicalProperties(boardProps);
// Replace the boards with a real ones
boards = new ArrayList<>();
for (Map.Entry<String, HierarchicalProperties> entry : boardsFile.getChildren().entrySet()) {
if (entry.getValue().getChild("name") != null) { //$NON-NLS-1$
// assume things with names are boards
boards.add(new ArduinoBoard(entry.getKey(), entry.getValue()).setOwners(this));
}
}
}
return boards;
}
public ArduinoBoard getBoard(String name) throws CoreException {
for (ArduinoBoard board : getBoards()) {
if (name.equals(board.getName())) {
return board;
}
}
return null;
}
public List<ToolDependency> getToolsDependencies() {
return toolsDependencies;
}
public Properties getPlatformProperties() throws CoreException {
Properties properties = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
properties.load(reader);
return properties;
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading platform.txt", e));
}
}
public boolean isInstalled() {
return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$
}
private Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
.resolve(version);
}
public IStatus install(IProgressMonitor monitor) {
// Check if we're installed already
if (isInstalled()) {
return Status.OK_STATUS;
}
// Download platform archive
IStatus status = ArduinoBoardManager.downloadAndInstall(url, archiveFileName, getInstallPath(), monitor);
if (!status.isOK()) {
return status;
}
// Install the tools
MultiStatus mstatus = null;
for (ToolDependency toolDep : toolsDependencies) {
status = toolDep.install(monitor);
if (!status.isOK()) {
if (mstatus == null) {
mstatus = new MultiStatus(status.getPlugin(), status.getCode(), status.getMessage(),
status.getException());
} else {
mstatus.add(status);
}
}
}
// TODO on Windows install make from equations.org
return mstatus != null ? mstatus : Status.OK_STATUS;
}
}

View file

@ -0,0 +1,74 @@
/*******************************************************************************
* 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.board;
import java.nio.file.Path;
import java.util.List;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
public class ArduinoTool {
private String name;
private String version;
private List<ArduinoToolSystem> systems;
private transient ArduinoPackage pkg;
public void setOwner(ArduinoPackage pkg) {
this.pkg = pkg;
for (ArduinoToolSystem system : systems) {
system.setOwner(this);
}
}
public ArduinoPackage getPackage() {
return pkg;
}
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public List<ArduinoToolSystem> getSystems() {
return systems;
}
public Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("tools").resolve(pkg.getName()).resolve(name) //$NON-NLS-1$
.resolve(version);
}
public boolean isInstalled() {
return getInstallPath().toFile().exists();
}
public IStatus install(IProgressMonitor monitor) {
if (isInstalled()) {
return Status.OK_STATUS;
}
for (ArduinoToolSystem system : systems) {
if (system.isApplicable()) {
return system.install(monitor);
}
}
// No valid system
return new Status(IStatus.ERROR, Activator.getId(), "No valid system found for " + name);
}
}

View file

@ -0,0 +1,78 @@
/*******************************************************************************
* 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.board;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
public class ArduinoToolSystem {
private String host;
private String archiveFileName;
private String url;
private String checksum;
private String size;
private transient ArduinoTool tool;
public void setOwner(ArduinoTool tool) {
this.tool = tool;
}
public String getHost() {
return host;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getUrl() {
return url;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
public boolean isApplicable() {
switch (Platform.getOS()) {
case Platform.OS_WIN32:
return "i686-mingw32".equals(host); //$NON-NLS-1$
case Platform.OS_MACOSX:
switch (host) {
case "i386-apple-darwin11": //$NON-NLS-1$
case "x86_64-apple-darwin:": //$NON-NLS-1$
return true;
default:
return false;
}
case Platform.OS_LINUX:
switch (Platform.getOSArch()) {
case Platform.ARCH_X86_64:
return "x86_64-pc-linux-gnu".equals(host); //$NON-NLS-1$
case Platform.ARCH_X86:
return "i686-pc-linux-gnu".equals(host); //$NON-NLS-1$
default:
return false;
}
default:
return false;
}
}
public IStatus install(IProgressMonitor monitor) {
return ArduinoBoardManager.downloadAndInstall(url, archiveFileName, tool.getInstallPath(), monitor);
}
}

View file

@ -11,14 +11,14 @@ import java.util.List;
public class PackageIndex { public class PackageIndex {
private List<BoardPackage> packages; private List<ArduinoPackage> packages;
public List<BoardPackage> getPackages() { public List<ArduinoPackage> getPackages() {
return packages; return packages;
} }
public BoardPackage getPackage(String packageName) { public ArduinoPackage getPackage(String packageName) {
for (BoardPackage pkg : packages) { for (ArduinoPackage pkg : packages) {
if (pkg.getName().equals(packageName)) { if (pkg.getName().equals(packageName)) {
return pkg; return pkg;
} }
@ -27,8 +27,8 @@ public class PackageIndex {
} }
void setOwners(ArduinoBoardManager manager) { void setOwners(ArduinoBoardManager manager) {
for (BoardPackage pkg : packages) { for (ArduinoPackage pkg : packages) {
pkg.setOwners(manager); pkg.setOwner(manager);
} }
} }

View file

@ -1,216 +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.board;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.apache.commons.compress.archivers.ArchiveEntry;
import org.apache.commons.compress.archivers.ArchiveException;
import org.apache.commons.compress.archivers.ArchiveInputStream;
import org.apache.commons.compress.archivers.ArchiveStreamFactory;
import org.apache.commons.compress.compressors.CompressorException;
import org.apache.commons.compress.compressors.CompressorStreamFactory;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoPreferences;
import org.eclipse.cdt.arduino.core.internal.HierarchicalProperties;
import org.eclipse.cdt.arduino.core.internal.Messages;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
@SuppressWarnings("restriction")
public class Platform {
private String name;
private String architecture;
private String version;
private String category;
private String url;
private String archiveFileName;
private String checksum;
private String size;
private List<Board> boards;
private List<ToolDependency> toolsDependencies;
private transient BoardPackage pkg;
private transient HierarchicalProperties boardsFile;
void setOwners(BoardPackage pkg) {
this.pkg = pkg;
for (Board board : boards) {
board.setOwners(this);
}
}
public BoardPackage getPackage() {
return pkg;
}
public String getName() {
return name;
}
public String getArchitecture() {
return architecture;
}
public String getVersion() {
return version;
}
public String getCategory() {
return category;
}
public String getUrl() {
return url;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
public List<Board> getBoards() throws CoreException {
if (isInstalled() && boardsFile == null) {
Properties boardProps = new Properties();
try (Reader reader = new FileReader(getInstallPath().resolve("boards.txt").toFile())) { //$NON-NLS-1$
boardProps.load(reader);
} catch (IOException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Loading boards", e));
}
boardsFile = new HierarchicalProperties(boardProps);
// Replace the boards with a real ones
boards = new ArrayList<>();
for (HierarchicalProperties child : boardsFile.getChildren().values()) {
if (child.getChild("name") != null) { //$NON-NLS-1$
// assume things with names are boards
boards.add(new Board(child).setOwners(this));
}
}
}
return boards;
}
public Board getBoard(String boardId) throws CoreException {
for (Board board : getBoards()) {
if (boardId.equals(board.getId())) {
return board;
}
}
return null;
}
public List<ToolDependency> getToolsDependencies() {
return toolsDependencies;
}
public boolean isInstalled() {
return getInstallPath().resolve("boards.txt").toFile().exists(); //$NON-NLS-1$
}
private Path getInstallPath() {
return ArduinoPreferences.getArduinoHome().resolve("hardware").resolve(pkg.getName()).resolve(architecture) //$NON-NLS-1$
.resolve(version);
}
public IStatus install(IProgressMonitor monitor) throws CoreException {
try {
try (CloseableHttpClient client = HttpClients.createDefault()) {
HttpGet get = new HttpGet(url);
try (CloseableHttpResponse response = client.execute(get)) {
if (response.getStatusLine().getStatusCode() >= 400) {
return new Status(IStatus.ERROR, Activator.getId(), response.getStatusLine().getReasonPhrase());
} else {
HttpEntity entity = response.getEntity();
if (entity == null) {
return new Status(IStatus.ERROR, Activator.getId(), Messages.ArduinoBoardManager_1);
}
// the archive has the version number as the root
// directory
Path installPath = getInstallPath().getParent();
Files.createDirectories(installPath);
Path archivePath = installPath.resolve(archiveFileName);
Files.copy(entity.getContent(), archivePath, StandardCopyOption.REPLACE_EXISTING);
// extract
ArchiveInputStream archiveIn = null;
try {
String compressor = null;
String archiver = null;
if (archiveFileName.endsWith("tar.bz2")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.BZIP2;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.gz") || archiveFileName.endsWith(".tgz")) { //$NON-NLS-1$ //$NON-NLS-2$
compressor = CompressorStreamFactory.GZIP;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".tar.xz")) { //$NON-NLS-1$
compressor = CompressorStreamFactory.XZ;
archiver = ArchiveStreamFactory.TAR;
} else if (archiveFileName.endsWith(".zip")) { //$NON-NLS-1$
archiver = ArchiveStreamFactory.ZIP;
}
InputStream in = new BufferedInputStream(new FileInputStream(archivePath.toFile()));
if (compressor != null) {
in = new CompressorStreamFactory().createCompressorInputStream(compressor, in);
}
archiveIn = new ArchiveStreamFactory().createArchiveInputStream(archiver, in);
for (ArchiveEntry entry = archiveIn.getNextEntry(); entry != null; entry = archiveIn
.getNextEntry()) {
if (entry.isDirectory()) {
continue;
}
// TODO check for soft links in tar files.
Path entryPath = installPath.resolve(entry.getName());
Files.createDirectories(entryPath.getParent());
Files.copy(archiveIn, entryPath, StandardCopyOption.REPLACE_EXISTING);
}
} finally {
if (archiveIn != null) {
archiveIn.close();
}
}
}
}
}
return Status.OK_STATUS;
} catch (IOException | CompressorException | ArchiveException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Installing Platform", e));
}
}
}

View file

@ -1,30 +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.board;
import java.util.List;
public class Tool {
private String name;
private String version;
private List<ToolSystem> systems;
public String getName() {
return name;
}
public String getVersion() {
return version;
}
public List<ToolSystem> getSystems() {
return systems;
}
}

View file

@ -7,12 +7,24 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.board; package org.eclipse.cdt.arduino.core.internal.board;
import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
public class ToolDependency { public class ToolDependency {
private String packager; private String packager;
private String name; private String name;
private String version; private String version;
private transient ArduinoPlatform platform;
public void setOwner(ArduinoPlatform platform) {
this.platform = platform;
}
public String getPackager() { public String getPackager() {
return packager; return packager;
} }
@ -25,4 +37,26 @@ public class ToolDependency {
return version; return version;
} }
public ArduinoTool getTool() throws CoreException {
ArduinoPackage pkg = platform.getPackage();
if (!pkg.getName().equals(packager)) {
pkg = pkg.getManager().getPackageIndex().getPackage(packager);
}
return pkg.getTool(name, version);
}
public IStatus install(IProgressMonitor monitor) {
try {
ArduinoTool tool = getTool();
if (tool == null) {
return new Status(IStatus.ERROR, Activator.getId(),
String.format("Tool not found %s %s", name, version));
}
return getTool().install(monitor);
} catch (CoreException e) {
return e.getStatus();
}
}
} }

View file

@ -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.core.internal.board;
public class ToolSystem {
private String host;
private String archiveFileName;
private String url;
private String checksum;
private String size;
public String getHost() {
return host;
}
public String getArchiveFileName() {
return archiveFileName;
}
public String getUrl() {
return url;
}
public String getChecksum() {
return checksum;
}
public String getSize() {
return size;
}
}

View file

@ -0,0 +1,73 @@
package org.eclipse.cdt.arduino.core.internal.build;
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.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.core.resources.IBuildConfiguration;
import org.eclipse.core.resources.ProjectScope;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IAdapterFactory;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.osgi.service.prefs.BackingStoreException;
public class ArduinoBuildConfiguration {
private static final String PACKAGE_NAME = "packageId";
private static final String PLATFORM_NAME = "platformName";
private static final String BOARD_NAME = "boardName";
private final IBuildConfiguration config;
private ArduinoBuildConfiguration(IBuildConfiguration config) {
this.config = config;
}
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) {
return (T) new ArduinoBuildConfiguration((IBuildConfiguration) adaptableObject);
}
return null;
}
@Override
public Class<?>[] getAdapterList() {
return new Class<?>[] { ArduinoBuildConfiguration.class };
}
}
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 {
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());
try {
settings.flush();
} catch (BackingStoreException e) {
throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Saving preferences", e));
}
}
public ArduinoBoard getBoard() throws CoreException {
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$
return ArduinoBoardManager.instance.getBoard(boardName, platformName, packageName);
}
}

View file

@ -7,21 +7,34 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal.build; package org.eclipse.cdt.arduino.core.internal.build;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import java.util.Map;
import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoProjectNature; import org.eclipse.cdt.arduino.core.internal.ArduinoTemplateGenerator;
import org.eclipse.cdt.core.settings.model.CProjectDescriptionEvent; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription; import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.managedbuilder.core.IConfiguration; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.managedbuilder.core.IManagedBuildInfo; import org.eclipse.cdt.core.model.CoreModel;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager; import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.model.IOutputEntry;
import org.eclipse.cdt.core.model.IPathEntry;
import org.eclipse.cdt.core.model.ISourceRoot;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject; 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.IncrementalProjectBuilder; import org.eclipse.core.resources.IncrementalProjectBuilder;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
/** /**
* This class is responsible for generating the Makefile for the current build * This class is responsible for generating the Makefile for the current build
@ -33,36 +46,101 @@ public class ArduinoBuilder extends IncrementalProjectBuilder {
@Override @Override
protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException { protected IProject[] build(int kind, Map<String, String> args, IProgressMonitor monitor) throws CoreException {
IManagedBuildInfo info = ManagedBuildManager.getBuildInfo(getProject()); IProject project = getProject();
IConfiguration config = info.getDefaultConfiguration();
// What board are we building for?
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
ArduinoBoard board = config.getBoard();
// Get the build console
ArduinoConsoleService consoleService = Activator.getConsoleService();
try {
consoleService.writeOutput(String.format("\nBuilding project: %s\n", project.getName()));
IFolder buildFolder = project.getFolder("build"); //$NON-NLS-1$
if (!buildFolder.exists()) {
buildFolder.create(true, true, monitor);
CoreModel.newOutputEntry(buildFolder.getFullPath());
}
String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
IFile makeFile = buildFolder.getFile(makeFileName);
generateMakefile(makeFile, board, monitor);
String[] cmd = new String[] { "make", "-f", makeFileName }; //$NON-NLS-1$ //$NON-NLS-2$
Process process = Runtime.getRuntime().exec(cmd, null, new File(buildFolder.getLocationURI()));
consoleService.monitor(process, null);
buildFolder.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 // TODO if there are references we want to watch, return them here
return null; return new IProject[] { project };
} }
public static void handleProjectDescEvent(CProjectDescriptionEvent event) { @Override
protected void clean(IProgressMonitor monitor) throws CoreException {
IProject project = getProject();
ArduinoBuildConfiguration config = getBuildConfig().getAdapter(ArduinoBuildConfiguration.class);
ArduinoBoard board = config.getBoard();
ArduinoConsoleService consoleService = Activator.getConsoleService();
try { try {
IProject project = event.getProject(); consoleService.writeOutput(String.format("\nCleaning project: %s\n", project.getName()));
// Is this an arduino project?
if (!ArduinoProjectNature.hasNature(project)) { IFolder buildFolder = project.getFolder("build"); //$NON-NLS-1$
return; if (!buildFolder.exists()) {
buildFolder.create(true, true, monitor);
ICProject cproject = CoreModel.getDefault().create(project);
IOutputEntry output = CoreModel.newOutputEntry(buildFolder.getFullPath());
IPathEntry[] oldEntries = cproject.getRawPathEntries();
IPathEntry[] newEntries = new IPathEntry[oldEntries.length];
System.arraycopy(oldEntries, 0, newEntries, 0, oldEntries.length);
newEntries[oldEntries.length] = output;
cproject.setRawPathEntries(newEntries, monitor);
} }
// See if CDT config changed and sync the Resource config String makeFileName = board.getId() + ".mk"; //$NON-NLS-1$
ICConfigurationDescription newConfigDesc = event.getNewCProjectDescription().getActiveConfiguration(); IFile makeFile = buildFolder.getFile(makeFileName);
ICConfigurationDescription oldConfigDesc = event.getOldCProjectDescription().getActiveConfiguration(); generateMakefile(makeFile, board, monitor);
if (!newConfigDesc.equals(oldConfigDesc)) {
System.out.println("Active config changed: " + newConfigDesc.getName()); //$NON-NLS-1$ String[] cmd = new String[] { "make", "-f", makeFileName, "clean" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
String configName = newConfigDesc.getName(); Process process = Runtime.getRuntime().exec(cmd, null, new File(buildFolder.getLocationURI()));
if (project.hasBuildConfig(configName)) {
IProjectDescription projDesc = project.getDescription(); consoleService.monitor(process, null);
projDesc.setActiveBuildConfig(configName);
project.setDescription(projDesc, new NullProgressMonitor()); buildFolder.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} } catch (IOException e) {
} throw new CoreException(new Status(IStatus.ERROR, Activator.getId(), "Build error", e));
} catch (CoreException e) {
Activator.log(e);
} }
} }
private void generateMakefile(IFile makeFile, ArduinoBoard board, IProgressMonitor monitor) throws CoreException {
Map<String, Object> buildModel = new HashMap<>();
buildModel.put("boardId", board.getId()); //$NON-NLS-1$
final List<String> sourceFiles = new ArrayList<>();
final IProject project = getProject();
for (ISourceRoot sourceRoot : CCorePlugin.getDefault().getCoreModel().create(project).getSourceRoots()) {
sourceRoot.getResource().accept(new IResourceProxyVisitor() {
@Override
public boolean visit(IResourceProxy proxy) throws CoreException {
if (proxy.getType() == IResource.FILE) {
if (CoreModel.isValidSourceUnitName(project, proxy.getName())) {
sourceFiles.add(proxy.getName());
}
}
return true;
}
}, 0);
}
buildModel.put("sources", sourceFiles); //$NON-NLS-1$
ArduinoTemplateGenerator templateGen = new ArduinoTemplateGenerator();
templateGen.generateFile(buildModel, "board.mk", makeFile, monitor); //$NON-NLS-1$
}
} }

View file

@ -8,16 +8,21 @@
* Contributors: * Contributors:
* QNX Software Systems - Initial API and implementation * QNX Software Systems - Initial API and implementation
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.core.internal; package org.eclipse.cdt.arduino.core.internal.console;
import java.io.IOException;
public interface ArduinoLaunchConsoleService { public interface ArduinoConsoleService {
/** /**
* Capture the output for the process and display on the console. * Capture the output for the process and display on the console.
* *
* @param process * @param process
*/ */
void monitor(Process process); void monitor(Process process, ConsoleParser[] consoleParsers) throws IOException;
void writeOutput(String msg) throws IOException;
void writeError(String msg) throws IOException;
} }

View file

@ -0,0 +1,48 @@
package org.eclipse.cdt.arduino.core.internal.console;
import java.nio.file.Path;
public interface ConsoleParser {
/**
* 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();
/**
* 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();
/**
* 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();
/**
* The pattern has been matched. Perform any necessary actions. Generally
* this would include creating markers for the errors.
*
* @param text text that matched the pattern
* @param directory calculated current directory
*/
public void patternMatched(String text, Path directory);
}

View file

@ -16,25 +16,14 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.arduino.core.internal.Activator; import org.eclipse.cdt.arduino.core.internal.Activator;
import org.eclipse.cdt.arduino.core.internal.ArduinoLaunchConsoleService;
import org.eclipse.cdt.arduino.core.internal.IArduinoRemoteConnection; import org.eclipse.cdt.arduino.core.internal.IArduinoRemoteConnection;
import org.eclipse.cdt.arduino.core.internal.Messages; import org.eclipse.cdt.arduino.core.internal.Messages;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.arduino.core.internal.board.Board;
import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection; import org.eclipse.cdt.arduino.core.internal.remote.ArduinoRemoteConnection;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.envvar.IEnvironmentVariable;
import org.eclipse.cdt.core.settings.model.ICConfigurationDescription;
import org.eclipse.cdt.core.settings.model.ICProjectDescription;
import org.eclipse.cdt.managedbuilder.core.IConfiguration;
import org.eclipse.cdt.managedbuilder.core.ManagedBuildManager;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IExtension;
import org.eclipse.core.runtime.IExtensionPoint;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.debug.core.DebugPlugin; import org.eclipse.debug.core.DebugPlugin;
@ -64,19 +53,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
// 1. make sure proper build config is set active // 1. make sure proper build config is set active
IProject project = configuration.getMappedResources()[0].getProject(); IProject project = configuration.getMappedResources()[0].getProject();
ICProjectDescription projDesc = CCorePlugin.getDefault().getProjectDescription(project); // TODO set active build config for the selected target
ICConfigurationDescription configDesc = getBuildConfiguration(projDesc, target);
boolean newConfig = false;
if (configDesc == null) {
IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class);
configDesc = ArduinoBoardManager.instance.createBuildConfiguration(projDesc, arduinoRemote.getBoardName(),
arduinoRemote.getPlatformName(), arduinoRemote.getPackageName());
newConfig = true;
}
if (newConfig || !projDesc.getActiveConfiguration().equals(configDesc)) {
projDesc.setActiveConfiguration(configDesc);
CCorePlugin.getDefault().setProjectDescription(project, projDesc);
}
// 2. Run the build // 2. Run the build
return super.buildForLaunch(configuration, mode, monitor); return super.buildForLaunch(configuration, mode, monitor);
@ -95,7 +72,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
new Job(Messages.ArduinoLaunchConfigurationDelegate_0) { new Job(Messages.ArduinoLaunchConfigurationDelegate_0) {
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
try { try {
ArduinoLaunchConsoleService consoleService = getConsoleService(); ArduinoConsoleService consoleService = Activator.getConsoleService();
IRemoteConnection target = getTarget(configuration); IRemoteConnection target = getTarget(configuration);
if (target == null) { if (target == null) {
return new Status(IStatus.ERROR, Activator.getId(), return new Status(IStatus.ERROR, Activator.getId(),
@ -106,14 +83,8 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
IProject project = (IProject) configuration.getMappedResources()[0]; IProject project = (IProject) configuration.getMappedResources()[0];
// The build environment // The build environment
ICProjectDescription projDesc = CCorePlugin.getDefault().getProjectDescription(project); List<String> envVarList = new ArrayList<>();
ICConfigurationDescription configDesc = getBuildConfiguration(projDesc, target);
IEnvironmentVariable[] envVars = CCorePlugin.getDefault().getBuildEnvironmentManager()
.getVariables(configDesc, true);
List<String> envVarList = new ArrayList<String>(envVars.length + 1);
for (IEnvironmentVariable var : envVars) {
envVarList.add(var.getName() + '=' + var.getValue());
}
// Add in the serial port based on launch config // Add in the serial port based on launch config
IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class); IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class);
envVarList.add("SERIAL_PORT=" + arduinoRemote.getPortName()); //$NON-NLS-1$ envVarList.add("SERIAL_PORT=" + arduinoRemote.getPortName()); //$NON-NLS-1$
@ -123,8 +94,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
File projectDir = new File(project.getLocationURI()); File projectDir = new File(project.getLocationURI());
// The build command // The build command
IConfiguration buildConfig = ManagedBuildManager.getConfigurationForDescription(configDesc); String command = "make";
String command = buildConfig.getBuilder().getCommand();
// If opened, temporarily close the connection so we can use // If opened, temporarily close the connection so we can use
// it to download the firmware. // it to download the firmware.
@ -135,7 +105,7 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
// Run the process and capture the results in the console // Run the process and capture the results in the console
Process process = Runtime.getRuntime().exec(command + " load", envp, projectDir); //$NON-NLS-1$ Process process = Runtime.getRuntime().exec(command + " load", envp, projectDir); //$NON-NLS-1$
consoleService.monitor(process); consoleService.monitor(process, null);
try { try {
process.waitFor(); process.waitFor();
} catch (InterruptedException e) { } catch (InterruptedException e) {
@ -158,46 +128,4 @@ public class ArduinoLaunchConfigurationDelegate extends LaunchConfigurationDeleg
}.schedule(); }.schedule();
} }
private ArduinoLaunchConsoleService getConsoleService() throws CoreException {
IExtensionPoint point = Platform.getExtensionRegistry().getExtensionPoint(Activator.getId(), "consoleService"); //$NON-NLS-1$
IExtension extension = point.getExtensions()[0]; // should only be one
return (ArduinoLaunchConsoleService) extension.getConfigurationElements()[0].createExecutableExtension("class"); //$NON-NLS-1$
}
/**
* Returns the build configuration for the active target and the launch
* configuration.
*
* @param launchConfig
* @return
*/
private ICConfigurationDescription getBuildConfiguration(ICProjectDescription projDesc, IRemoteConnection target)
throws CoreException {
String boardName;
String platformName;
String packageName;
if (target != null) {
IArduinoRemoteConnection arduinoRemote = target.getService(IArduinoRemoteConnection.class);
boardName = arduinoRemote.getBoardName();
platformName = arduinoRemote.getPlatformName();
packageName = arduinoRemote.getPackageName();
} else {
// TODO
boardName = "Arduino Uno"; //$NON-NLS-1$
platformName = "Arduino AVR Boards"; //$NON-NLS-1$
packageName = "arduino"; //$NON-NLS-1$
}
for (ICConfigurationDescription configDesc : projDesc.getConfigurations()) {
IConfiguration config = ManagedBuildManager.getConfigurationForDescription(configDesc);
Board board = ArduinoBoardManager.instance.getBoard(config);
if (boardName.equals(board.getId()) && platformName.equals(board.getPlatform().getArchitecture())
&& packageName.equals(board.getPlatform().getPackage().getName())) {
return configDesc;
}
}
return null;
}
} }

View file

@ -0,0 +1,21 @@
OUTPUT_DIR = ${boardId}
ifeq ($(OS),Windows_NT)
RMDIR = rmdir /s /q
mymkdir = if not exist "$(call fixpath,$1)" mkdir $(call fixpath,$1)
else
RMDIR = rm -fr
mymkdir = mkdir -p $1
endif
SOURCES = \
<#list sources as file>
../src/${file} \
</#list>
all:
@$(call mymkdir,$(OUTPUT_DIR))
echo hello from template
clean:
$(RMDIR) $(OUTPUT_DIR)

View file

@ -33,7 +33,7 @@
<extension <extension
point="org.eclipse.cdt.arduino.core.consoleService"> point="org.eclipse.cdt.arduino.core.consoleService">
<provider <provider
class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoLaunchConsole"> class="org.eclipse.cdt.arduino.ui.internal.launch.ArduinoConsole">
</provider> </provider>
</extension> </extension>
<extension <extension

View file

@ -11,6 +11,7 @@
package org.eclipse.cdt.arduino.ui.internal; package org.eclipse.cdt.arduino.ui.internal;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.InstanceScope; import org.eclipse.core.runtime.preferences.InstanceScope;
@ -18,6 +19,7 @@ import org.eclipse.jface.preference.IPreferenceStore;
import org.eclipse.jface.resource.ImageRegistry; import org.eclipse.jface.resource.ImageRegistry;
import org.eclipse.ui.plugin.AbstractUIPlugin; import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.preferences.ScopedPreferenceStore; import org.eclipse.ui.preferences.ScopedPreferenceStore;
import org.eclipse.ui.progress.UIJob;
import org.osgi.framework.BundleContext; import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference; import org.osgi.framework.ServiceReference;
@ -41,9 +43,14 @@ public class Activator extends AbstractUIPlugin {
super.start(context); super.start(context);
plugin = this; plugin = this;
ImageRegistry imageRegistry = getImageRegistry(); new UIJob("Arduino UI Startup") {
imageRegistry.put(IMG_ARDUINO, imageDescriptorFromPlugin(PLUGIN_ID, "icons/cprojects.gif")); //$NON-NLS-1$ public IStatus runInUIThread(IProgressMonitor monitor) {
imageRegistry.put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arduino.png")); //$NON-NLS-1$ ImageRegistry imageRegistry = getImageRegistry();
imageRegistry.put(IMG_ARDUINO, imageDescriptorFromPlugin(PLUGIN_ID, "icons/cprojects.gif")); //$NON-NLS-1$
imageRegistry.put(IMG_CONNECTION_TYPE, imageDescriptorFromPlugin(PLUGIN_ID, "icons/arduino.png")); //$NON-NLS-1$
return Status.OK_STATUS;
}
}.schedule();
} }
public void stop(BundleContext context) throws Exception { public void stop(BundleContext context) throws Exception {

View file

@ -7,7 +7,6 @@ public class Messages extends NLS {
public static String ArduinoLaunchConsole_0; public static String ArduinoLaunchConsole_0;
public static String ArduinoLaunchConsole_1; public static String ArduinoLaunchConsole_1;
public static String ArduinoLaunchConsole_2; public static String ArduinoLaunchConsole_2;
public static String ArduinoLaunchConsole_3;
public static String ArduinoPreferencePage_0; public static String ArduinoPreferencePage_0;
public static String ArduinoPreferencePage_1; public static String ArduinoPreferencePage_1;
public static String ArduinoTargetPropertyPage_0; public static String ArduinoTargetPropertyPage_0;

View file

@ -0,0 +1,114 @@
/*******************************************************************************
* 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.concurrent.Semaphore;
import org.eclipse.cdt.arduino.core.internal.console.ArduinoConsoleService;
import org.eclipse.cdt.arduino.core.internal.console.ConsoleParser;
import org.eclipse.cdt.arduino.ui.internal.Messages;
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 {
private static MessageConsole console;
private static MessageConsoleStream out;
private static MessageConsoleStream err;
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));
}
});
}
}
@Override
public void monitor(final Process process, ConsoleParser[] consoleParsers) throws IOException {
// console.clearConsole();
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();
int rc = process.waitFor();
if (rc != 0) {
writeError("failed.");
}
} catch (InterruptedException e) {
// TODO
e.printStackTrace();
}
}
@Override
public void writeOutput(String msg) throws IOException {
out.write(msg);
}
@Override
public void writeError(String msg) throws IOException {
err.write(msg);
}
}

View file

@ -1,81 +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.IOException;
import java.io.InputStream;
import org.eclipse.cdt.arduino.core.internal.ArduinoLaunchConsoleService;
import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
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.IOConsoleOutputStream;
import org.eclipse.ui.console.MessageConsole;
import org.eclipse.ui.progress.UIJob;
public class ArduinoLaunchConsole implements ArduinoLaunchConsoleService {
private static MessageConsole console;
public ArduinoLaunchConsole() {
if (console == null) {
console = new MessageConsole(Messages.ArduinoLaunchConsole_0, null);
ConsolePlugin.getDefault().getConsoleManager().addConsoles(new IConsole[] { console });
}
}
@Override
public void monitor(final Process process) {
console.clearConsole();
console.activate();
new UIJob(Messages.ArduinoLaunchConsole_1) {
@Override
public IStatus runInUIThread(IProgressMonitor monitor) {
final IOConsoleOutputStream out = console.newOutputStream();
out.setColor(Display.getDefault().getSystemColor(SWT.COLOR_BLACK));
new Thread(Messages.ArduinoLaunchConsole_2) {
public void run() {
try (InputStream processOut = process.getInputStream()) {
for (int c = processOut.read(); c >= 0; c = processOut.read()) {
out.write(c);
}
} catch (IOException e) {
// Nothing. Just exit
}
}
}.start();
final IOConsoleOutputStream err = console.newOutputStream();
err.setColor(Display.getDefault().getSystemColor(SWT.COLOR_RED));
new Thread(Messages.ArduinoLaunchConsole_3) {
public void run() {
try (InputStream processErr = process.getErrorStream()) {
for (int c = processErr.read(); c >= 0; c = processErr.read()) {
err.write(c);
}
} catch (IOException e) {
// Nothing. Just exit
}
}
}.start();
return Status.OK_STATUS;
}
}.schedule();
}
}

View file

@ -1,7 +1,6 @@
ArduinoLaunchConsole_0=Arduino Launch ArduinoLaunchConsole_0=Arduino
ArduinoLaunchConsole_1=Start Arduino Console ArduinoLaunchConsole_1=Start Arduino Console
ArduinoLaunchConsole_2=Arduino Launch Console Output ArduinoLaunchConsole_2=Arduino Console Output
ArduinoLaunchConsole_3=Arduino Launch Console Output
ArduinoPreferencePage_0=Arduino IDE Install Location ArduinoPreferencePage_0=Arduino IDE Install Location
ArduinoPreferencePage_1=Arduino C++ Preferences ArduinoPreferencePage_1=Arduino C++ Preferences
ArduinoTargetPropertyPage_0=Serial Port: ArduinoTargetPropertyPage_0=Serial Port:

View file

@ -7,7 +7,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.arduino.ui.internal.preferences; package org.eclipse.cdt.arduino.ui.internal.preferences;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Comparator; import java.util.Comparator;
@ -15,16 +14,16 @@ import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board; import org.eclipse.cdt.arduino.core.internal.board.ArduinoPackage;
import org.eclipse.cdt.arduino.core.internal.board.BoardPackage; import org.eclipse.cdt.arduino.core.internal.board.ArduinoPlatform;
import org.eclipse.cdt.arduino.core.internal.board.PackageIndex; import org.eclipse.cdt.arduino.core.internal.board.PackageIndex;
import org.eclipse.cdt.arduino.core.internal.board.Platform;
import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status; import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.jobs.Job; import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.jface.layout.TableColumnLayout; import org.eclipse.jface.layout.TableColumnLayout;
import org.eclipse.jface.preference.PreferencePage; import org.eclipse.jface.preference.PreferencePage;
@ -47,7 +46,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
private Table table; private Table table;
private Button installButton; private Button installButton;
private Set<Board> toInstall = new HashSet<>(); private Set<ArduinoBoard> toInstall = new HashSet<>();
@Override @Override
public void init(IWorkbench workbench) { public void init(IWorkbench workbench) {
@ -100,7 +99,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
@Override @Override
public void handleEvent(Event event) { public void handleEvent(Event event) {
for (TableItem item : table.getSelection()) { for (TableItem item : table.getSelection()) {
Board board = (Board) item.getData(); ArduinoBoard board = (ArduinoBoard) item.getData();
toInstall.add(board); toInstall.add(board);
item.setText(2, "selected"); item.setText(2, "selected");
updateButtons(); updateButtons();
@ -123,11 +122,11 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
try { try {
PackageIndex packageIndex = ArduinoBoardManager.instance.getPackageIndex(); PackageIndex packageIndex = ArduinoBoardManager.instance.getPackageIndex();
List<Board> boards = new ArrayList<>(); List<ArduinoBoard> boards = new ArrayList<>();
for (BoardPackage pkg : packageIndex.getPackages()) { for (ArduinoPackage pkg : packageIndex.getPackages()) {
for (Platform platform : pkg.getLatestPlatforms()) { for (ArduinoPlatform platform : pkg.getLatestPlatforms()) {
try { try {
for (Board board : platform.getBoards()) { for (ArduinoBoard board : platform.getBoards()) {
boards.add(board); boards.add(board);
} }
} catch (CoreException e) { } catch (CoreException e) {
@ -136,13 +135,13 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
} }
} }
Collections.sort(boards, new Comparator<Board>() { Collections.sort(boards, new Comparator<ArduinoBoard>() {
public int compare(Board o1, Board o2) { public int compare(ArduinoBoard o1, ArduinoBoard o2) {
return o1.getName().compareTo(o2.getName()); return o1.getName().compareTo(o2.getName());
} }
}); });
for (Board board : boards) { for (ArduinoBoard board : boards) {
TableItem item = new TableItem(table, SWT.NONE); TableItem item = new TableItem(table, SWT.NONE);
item.setData(board); item.setData(board);
item.setText(0, board.getName()); item.setText(0, board.getName());
@ -155,7 +154,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
} }
item.setText(2, msg); item.setText(2, msg);
} }
} catch (IOException e) { } catch (CoreException e) {
Activator.log(e); Activator.log(e);
} }
} }
@ -167,11 +166,11 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
boolean enable = false; boolean enable = false;
for (TableItem item : table.getSelection()) { for (TableItem item : table.getSelection()) {
Board board = (Board) item.getData(); ArduinoBoard board = (ArduinoBoard) item.getData();
if (toInstall.contains(board)) { if (toInstall.contains(board)) {
continue; continue;
} }
Platform platform = board.getPlatform(); ArduinoPlatform platform = board.getPlatform();
if (!platform.isInstalled()) { if (!platform.isInstalled()) {
enable = true; enable = true;
} }
@ -184,17 +183,15 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
new Job("Installing Arduino Board Platforms") { new Job("Installing Arduino Board Platforms") {
@Override @Override
protected IStatus run(IProgressMonitor monitor) { protected IStatus run(IProgressMonitor monitor) {
Set<Platform> platforms = new HashSet<>(); Set<ArduinoPlatform> platforms = new HashSet<>();
for (Board board : toInstall) { for (ArduinoBoard board : toInstall) {
platforms.add(board.getPlatform()); platforms.add(board.getPlatform());
} }
for (Platform platform : platforms) { MultiStatus status = new MultiStatus(Activator.PLUGIN_ID, 0, "Installing Arduino Board Platforms",
try { null);
platform.install(monitor); for (ArduinoPlatform platform : platforms) {
} catch (CoreException e) { status.add(platform.install(monitor));
return e.getStatus();
}
} }
toInstall.clear(); toInstall.clear();
@ -208,7 +205,7 @@ public class ArduinoBoardsPreferencePage extends PreferencePage implements IWork
}); });
} }
return Status.OK_STATUS; return status;
} }
}.schedule(); }.schedule();
return true; return true;

View file

@ -5,7 +5,7 @@ import java.util.Collection;
import org.eclipse.cdt.arduino.core.internal.IArduinoRemoteConnection; import org.eclipse.cdt.arduino.core.internal.IArduinoRemoteConnection;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages; import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.cdt.serial.SerialPort; import org.eclipse.cdt.serial.SerialPort;
@ -28,7 +28,7 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
private Combo portSelector; private Combo portSelector;
private Combo boardSelector; private Combo boardSelector;
private Board[] boards; private ArduinoBoard[] boards;
@Override @Override
protected Control createContents(Composite parent) { protected Control createContents(Composite parent) {
@ -73,13 +73,13 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
boardSelector.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); boardSelector.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try { try {
Board currentBoard = ArduinoBoardManager.instance.getBoard(arduinoRemote.getBoardName(), ArduinoBoard currentBoard = ArduinoBoardManager.instance.getBoard(arduinoRemote.getBoardName(),
arduinoRemote.getPlatformName(), arduinoRemote.getPackageName()); arduinoRemote.getPlatformName(), arduinoRemote.getPackageName());
Collection<Board> boardList = ArduinoBoardManager.instance.getBoards(); Collection<ArduinoBoard> boardList = ArduinoBoardManager.instance.getBoards();
boards = new Board[boardList.size()]; boards = new ArduinoBoard[boardList.size()];
i = 0; i = 0;
int boardSel = 0; int boardSel = 0;
for (Board board : boardList) { for (ArduinoBoard board : boardList) {
boards[i] = board; boards[i] = board;
boardSelector.add(board.getName()); boardSelector.add(board.getName());
if (board.equals(currentBoard)) { if (board.equals(currentBoard)) {
@ -103,7 +103,7 @@ public class ArduinoTargetPropertyPage extends PropertyPage implements IWorkbenc
String portName = portSelector.getItem(portSelector.getSelectionIndex()); String portName = portSelector.getItem(portSelector.getSelectionIndex());
workingCopy.setAttribute(IArduinoRemoteConnection.PORT_NAME, portName); workingCopy.setAttribute(IArduinoRemoteConnection.PORT_NAME, portName);
Board board = boards[boardSelector.getSelectionIndex()]; ArduinoBoard board = boards[boardSelector.getSelectionIndex()];
workingCopy.setAttribute(IArduinoRemoteConnection.BOARD_ID, board.getId()); workingCopy.setAttribute(IArduinoRemoteConnection.BOARD_ID, board.getId());
try { try {

View file

@ -3,7 +3,7 @@ package org.eclipse.cdt.arduino.ui.internal.remote;
import java.io.IOException; import java.io.IOException;
import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoardManager;
import org.eclipse.cdt.arduino.core.internal.board.Board; import org.eclipse.cdt.arduino.core.internal.board.ArduinoBoard;
import org.eclipse.cdt.arduino.ui.internal.Activator; import org.eclipse.cdt.arduino.ui.internal.Activator;
import org.eclipse.cdt.arduino.ui.internal.Messages; import org.eclipse.cdt.arduino.ui.internal.Messages;
import org.eclipse.cdt.serial.SerialPort; import org.eclipse.cdt.serial.SerialPort;
@ -30,8 +30,8 @@ public class NewArduinoTargetWizardPage extends WizardPage {
private String[] portNames; private String[] portNames;
private Combo portCombo; private Combo portCombo;
Board board; ArduinoBoard board;
private Board[] boards; private ArduinoBoard[] boards;
private Combo boardCombo; private Combo boardCombo;
public NewArduinoTargetWizardPage() { public NewArduinoTargetWizardPage() {
@ -90,8 +90,8 @@ public class NewArduinoTargetWizardPage extends WizardPage {
boardCombo = new Combo(comp, SWT.READ_ONLY); boardCombo = new Combo(comp, SWT.READ_ONLY);
boardCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL)); boardCombo.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
try { try {
boards = ArduinoBoardManager.instance.getBoards().toArray(new Board[0]); boards = ArduinoBoardManager.instance.getBoards().toArray(new ArduinoBoard[0]);
for (Board board : boards) { for (ArduinoBoard board : boards) {
boardCombo.add(board.getName()); boardCombo.add(board.getName());
} }
boardCombo.select(0); boardCombo.select(0);