From a71e46f94c70dddc8893fdb9a591b76ef27db1c2 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 4 Dec 2012 16:46:58 +0100 Subject: [PATCH 1/8] recursive library compilation triggered on multiplatform libraries --- app/src/processing/app/debug/Compiler.java | 56 +++++++++++++++------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 1bd8b8c25..ad3093842 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -40,6 +40,7 @@ import processing.app.Sketch; import processing.app.SketchCode; import processing.app.helpers.PreferencesMap; import processing.app.helpers.StringReplacer; +import processing.app.helpers.filefilters.OnlyDirs; import processing.core.PApplet; public class Compiler implements MessageConsumer { @@ -578,26 +579,47 @@ public class Compiler implements MessageConsumer { // 2. compile the libraries, outputting .o files to: // // void compileLibraries(List includePaths) throws RunnerException { - + File outputPath = new File(prefs.get("build.path")); for (File libraryFolder : sketch.getImportedLibraries()) { - String outputPath = prefs.get("build.path"); - File outputFolder = new File(outputPath, libraryFolder.getName()); - File utilityFolder = new File(libraryFolder, "utility"); - createFolder(outputFolder); - // this library can use includes in its utility/ folder - includePaths.add(utilityFolder.getAbsolutePath()); - - objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), - libraryFolder, false, includePaths)); - outputFolder = new File(outputFolder, "utility"); - createFolder(outputFolder); - objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), - utilityFolder, false, includePaths)); - // other libraries should not see this library's utility/ folder - includePaths.remove(includePaths.size() - 1); + if (new File(libraryFolder.getParentFile(), "library.properties").exists()) { + recursiveCompileLibrary(outputPath, libraryFolder, includePaths); + } else { + compileLibrary(outputPath, libraryFolder, includePaths); + } } } - + + private void recursiveCompileLibrary(File outputPath, File libraryFolder, List includePaths) throws RunnerException { + File newOutputPath = compileFilesInFolder(outputPath, libraryFolder, includePaths); + for (File subFolder : libraryFolder.listFiles(new OnlyDirs())) { + recursiveCompileLibrary(newOutputPath, subFolder, includePaths); + } + } + + private File compileFilesInFolder(File outputPath, File libraryFolder, List includePaths) throws RunnerException { + File outputFolder = new File(outputPath, libraryFolder.getName()); + createFolder(outputFolder); + objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), libraryFolder, false, includePaths)); + return outputFolder; + } + + private void compileLibrary(File outputPath, File libraryFolder, List includePaths) throws RunnerException { + File outputFolder = new File(outputPath, libraryFolder.getName()); + File utilityFolder = new File(libraryFolder, "utility"); + createFolder(outputFolder); + // this library can use includes in its utility/ folder + includePaths.add(utilityFolder.getAbsolutePath()); + + objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), + libraryFolder, false, includePaths)); + outputFolder = new File(outputFolder, "utility"); + createFolder(outputFolder); + objectFiles.addAll(compileFiles(outputFolder.getAbsolutePath(), + utilityFolder, false, includePaths)); + // other libraries should not see this library's utility/ folder + includePaths.remove(includePaths.size() - 1); + } + // 3. compile the core, outputting .o files to and then // collecting them into the core.a library file. void compileCore() From 2f4ce979694ccda356dea17674495780e365a6df Mon Sep 17 00:00:00 2001 From: vd Date: Sun, 6 Jan 2013 17:27:48 +0100 Subject: [PATCH 2/8] modified analogWrite to wait for end of conversion --- hardware/arduino/sam/cores/arduino/wiring_analog.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hardware/arduino/sam/cores/arduino/wiring_analog.c b/hardware/arduino/sam/cores/arduino/wiring_analog.c index 58bd87aca..97f50e80b 100644 --- a/hardware/arduino/sam/cores/arduino/wiring_analog.c +++ b/hardware/arduino/sam/cores/arduino/wiring_analog.c @@ -243,8 +243,8 @@ void analogWrite(uint32_t ulPin, uint32_t ulValue) { // Write user value ulValue = mapResolution(ulValue, _writeResolution, DACC_RESOLUTION); - while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_TXRDY) == 0); dacc_write_conversion_data(DACC_INTERFACE, ulValue); + while ((dacc_get_interrupt_status(DACC_INTERFACE) & DACC_ISR_EOC) == 0); return; } } From f8deaa5cfbf25d9e3687f54753dafcea1847e269 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Fri, 8 Feb 2013 18:12:53 +0100 Subject: [PATCH 3/8] Factoring Library class --- app/src/processing/app/Base.java | 130 ++++++++---------- app/src/processing/app/Sketch.java | 18 +-- app/src/processing/app/debug/Compiler.java | 14 +- app/src/processing/app/packages/Library.java | 79 +++++++++++ .../processing/app/packages/LibraryList.java | 30 ++++ .../processing/app/syntax/PdeKeywords.java | 5 +- 6 files changed, 184 insertions(+), 92 deletions(-) create mode 100644 app/src/processing/app/packages/Library.java create mode 100644 app/src/processing/app/packages/LibraryList.java diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index afa62e18b..057c80344 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -37,7 +37,9 @@ import processing.app.helpers.Maps; import processing.app.helpers.PreferencesMap; import processing.app.helpers.filefilters.OnlyDirs; import processing.app.helpers.filefilters.OnlyFilesWithExtension; -import processing.app.javax.swing.filechooser.FileNameExtensionFilter;import processing.app.tools.MapWithSubkeys; +import processing.app.javax.swing.filechooser.FileNameExtensionFilter;import processing.app.packages.Library; +import processing.app.packages.LibraryList; +import processing.app.tools.MapWithSubkeys; import processing.app.tools.ZipDeflater; import processing.core.*; import static processing.app.I18n._; @@ -89,10 +91,10 @@ public class Base { static private List librariesFolders; // maps library name to their library folder - static private Map libraries; + static private LibraryList libraries; // maps #included files to their library folder - static Map importToLibraryTable; + static Map importToLibraryTable; // classpath for all known libraries for p5 // (both those in the p5/libs folder and those with lib subfolders @@ -1038,26 +1040,26 @@ public class Base { } } - public Map getIDELibs() { + public LibraryList getIDELibs() { + LibraryList libs = new LibraryList(); if (libraries == null) - return new HashMap(); - Map ideLibs = new HashMap(libraries); - for (String lib : libraries.keySet()) { - if (FileUtils.isSubDirectory(getSketchbookFolder(), libraries.get(lib))) - ideLibs.remove(lib); + return libs; + for (Library lib : libraries) { + if (!FileUtils.isSubDirectory(getSketchbookFolder(), lib.getRootFolder())) + libs.add(lib); } - return ideLibs; + return libs; } - public Map getUserLibs() { + public LibraryList getUserLibs() { + LibraryList libs = new LibraryList(); if (libraries == null) - return new HashMap(); - Map userLibs = new HashMap(libraries); - for (String lib : libraries.keySet()) { - if (!FileUtils.isSubDirectory(getSketchbookFolder(), libraries.get(lib))) - userLibs.remove(lib); + return libs; + for (Library lib : libraries) { + if (FileUtils.isSubDirectory(getSketchbookFolder(), lib.getRootFolder())) + libs.add(lib); } - return userLibs; + return libs; } public void rebuildImportMenu(JMenu importMenu, final Editor editor) { @@ -1077,8 +1079,8 @@ public class Base { // Split between user supplied libraries and IDE libraries TargetPlatform targetPlatform = getTargetPlatform(); if (targetPlatform != null) { - Map ideLibs = getIDELibs(); - Map userLibs = getUserLibs(); + LibraryList ideLibs = getIDELibs(); + LibraryList userLibs = getUserLibs(); try { // Find the current target. Get the platform, and then select the // correct name and core path. @@ -1118,24 +1120,24 @@ public class Base { if (found) menu.addSeparator(); // Add examples from libraries - Map ideLibs = getIDELibs(); - List names = new ArrayList(ideLibs.keySet()); - Collections.sort(names, String.CASE_INSENSITIVE_ORDER); - for (String name : names) { - File folder = ideLibs.get(name); + LibraryList ideLibs = getIDELibs(); + Collections.sort(ideLibs, Library.CASE_INSENSITIVE_ORDER); + for (Library lib : ideLibs) { + File folder = lib.getRootFolder(); + String name = lib.getName(); addSketchesSubmenu(menu, name, folder, false); // Allows "fat" libraries to have examples in the root folder if (folder.getName().equals(Base.getTargetPlatform().getName())) addSketchesSubmenu(menu, name, folder.getParentFile(), false); } - Map userLibs = getUserLibs(); + LibraryList userLibs = getUserLibs(); if (userLibs.size()>0) { menu.addSeparator(); - names = new ArrayList(userLibs.keySet()); - Collections.sort(names, String.CASE_INSENSITIVE_ORDER); - for (String name : names) { - File folder = userLibs.get(name); + Collections.sort(userLibs, Library.CASE_INSENSITIVE_ORDER); + for (Library lib : userLibs) { + File folder = lib.getRootFolder(); + String name = lib.getName(); addSketchesSubmenu(menu, name, folder, false); // Allows "fat" libraries to have examples in the root folder if (folder.getName().equals(Base.getTargetPlatform().getName())) @@ -1147,15 +1149,16 @@ public class Base { } } - public Map scanLibraries(List folders) { - Map res = new HashMap(); + public LibraryList scanLibraries(List folders) { + LibraryList res = new LibraryList(); for (File folder : folders) - res.putAll(scanLibraries(folder)); + res.addAll(scanLibraries(folder)); return res; } - public Map scanLibraries(File folder) { - Map res = new HashMap(); + public LibraryList scanLibraries(File folder) { + LibraryList res = new LibraryList(); + String list[] = folder.list(new OnlyDirs()); // if a bad folder or something like that, this might come back null if (list == null) @@ -1172,41 +1175,15 @@ public class Base { continue; } - subfolder = scanFatLibrary(subfolder); + Library lib = Library.fromFolder(subfolder, Base.getTargetPlatform().getName()); // (also replace previously found libs with the same name) - if (subfolder != null) - res.put(libName, subfolder); + if (lib != null) + res.addOrReplace(lib); } return res; } - /** - * Scans inside a "FAT" (multi-platform) library folder to see if it contains - * a version suitable for the actual selected architecture. If a suitable - * version is found the folder containing that version is returned, otherwise - * null is returned.
- *
- * If a non-"FAT" library is detected, we assume that the library is suitable - * for the current architecture and the libFolder parameter is returned.
- * - * @param libFolder - * @return - */ - public File scanFatLibrary(File libFolder) { - // A library is considered "fat" if it contains a file called - // "library.properties" - File libraryPropFile = new File(libFolder, "library.properties"); - if (!libraryPropFile.exists() || !libraryPropFile.isFile()) - return libFolder; - - // Search for a subfolder for actual architecture, return null if not found - File archSubfolder = new File(libFolder, Base.getTargetPlatform().getName()); - if (!archSubfolder.exists() || !archSubfolder.isDirectory()) - return null; - return archSubfolder; - } - public void onBoardOrPortChange() { TargetPlatform targetPlatform = getTargetPlatform(); if (targetPlatform == null) @@ -1228,15 +1205,16 @@ public class Base { libraries = scanLibraries(librariesFolders); // Populate importToLibraryTable - importToLibraryTable = new HashMap(); - for (File subfolder : libraries.values()) { + importToLibraryTable = new HashMap(); + for (Library lib : libraries) { try { - String packages[] = headerListFromIncludePath(subfolder); - for (String pkg : packages) { - importToLibraryTable.put(pkg, subfolder); + String headers[] = headerListFromIncludePath(lib.getRootFolder()); + for (String header : headers) { + importToLibraryTable.put(header, lib); } } catch (IOException e) { - showWarning(_("Error"), I18n.format("Unable to list header files in {0}", subfolder), e); + showWarning(_("Error"), I18n + .format("Unable to list header files in {0}", lib.getRootFolder()), e); } } @@ -1580,10 +1558,10 @@ public class Base { return found; } - protected void addLibraries(JMenu menu, Map libs) throws IOException { + protected void addLibraries(JMenu menu, LibraryList libs) throws IOException { - List list = new ArrayList(libs.keySet()); - Collections.sort(list, String.CASE_INSENSITIVE_ORDER); + LibraryList list = new LibraryList(libs); + Collections.sort(list, Library.CASE_INSENSITIVE_ORDER); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent event) { @@ -1596,11 +1574,11 @@ public class Base { } }; - for (String name : list) { - File folder = libs.get(name); + for (Library lib : list) { + File folder = lib.getRootFolder(); // Add new element at the bottom - JMenuItem item = new JMenuItem(name); + JMenuItem item = new JMenuItem(lib.getName()); item.addActionListener(listener); item.setActionCommand(folder.getAbsolutePath()); menu.add(item); @@ -1874,7 +1852,7 @@ public class Base { } - static public Map getLibraries() { + static public LibraryList getLibraries() { return libraries; } diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index 6d84c70b9..df09bab1a 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -29,6 +29,8 @@ import processing.app.debug.RunnerException; import processing.app.debug.Sizer; import processing.app.debug.Uploader; import processing.app.helpers.PreferencesMap; +import processing.app.packages.Library; +import processing.app.packages.LibraryList; import processing.app.preproc.*; import processing.core.*; import static processing.app.I18n._; @@ -96,7 +98,7 @@ public class Sketch { /** * List of library folders. */ - private ArrayList importedLibraries; + private LibraryList importedLibraries; /** * path is location of the main .pde file, because this is also @@ -1421,18 +1423,18 @@ public class Sketch { // grab the imports from the code just preproc'd - importedLibraries = new ArrayList(); + importedLibraries = new LibraryList(); //Remember to clear library path before building it. libraryPath = ""; for (String item : preprocessor.getExtraImports()) { - File libFolder = (File) Base.importToLibraryTable.get(item); - //If needed can Debug libraryPath here + Library lib = Base.importToLibraryTable.get(item); + //If needed can Debug libraryPath here - if (libFolder != null && !importedLibraries.contains(libFolder)) { - importedLibraries.add(libFolder); + if (lib != null && !importedLibraries.contains(lib)) { + importedLibraries.add(lib); //classPath += Compiler.contentsToClassPath(libFolder); - libraryPath += File.pathSeparator + libFolder.getAbsolutePath(); + libraryPath += File.pathSeparator + lib.getRootFolder().getAbsolutePath(); } } @@ -1462,7 +1464,7 @@ public class Sketch { } - public ArrayList getImportedLibraries() { + public LibraryList getImportedLibraries() { return importedLibraries; } diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index ad3093842..ebb997116 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -41,6 +41,7 @@ import processing.app.SketchCode; import processing.app.helpers.PreferencesMap; import processing.app.helpers.StringReplacer; import processing.app.helpers.filefilters.OnlyDirs; +import processing.app.packages.Library; import processing.core.PApplet; public class Compiler implements MessageConsumer { @@ -84,8 +85,8 @@ public class Compiler implements MessageConsumer { includePaths.add(prefs.get("build.core.path")); if (prefs.get("build.variant.path").length() != 0) includePaths.add(prefs.get("build.variant.path")); - for (File file : sketch.getImportedLibraries()) - includePaths.add(file.getPath()); + for (Library lib : sketch.getImportedLibraries()) + includePaths.add(lib.getRootFolder().getPath()); // 1. compile the sketch (already in the buildPath) sketch.setCompilingProgress(30); @@ -580,11 +581,12 @@ public class Compiler implements MessageConsumer { // // void compileLibraries(List includePaths) throws RunnerException { File outputPath = new File(prefs.get("build.path")); - for (File libraryFolder : sketch.getImportedLibraries()) { - if (new File(libraryFolder.getParentFile(), "library.properties").exists()) { - recursiveCompileLibrary(outputPath, libraryFolder, includePaths); + for (Library lib : sketch.getImportedLibraries()) { + File libFolder = lib.getRootFolder(); + if (lib.isNewLib()) { + recursiveCompileLibrary(outputPath, libFolder, includePaths); } else { - compileLibrary(outputPath, libraryFolder, includePaths); + compileLibrary(outputPath, libFolder, includePaths); } } } diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java new file mode 100644 index 000000000..27f72254b --- /dev/null +++ b/app/src/processing/app/packages/Library.java @@ -0,0 +1,79 @@ +package processing.app.packages; + +import java.io.File; +import java.util.Comparator; +import java.util.List; + +public class Library { + + private String name; + private File folder; + private List architectures; + private boolean oldLib = true; + + /** + * Scans inside a library folder to see if it contains a version suitable for + * the actual selected architecture. If a suitable version is found the folder + * containing that version is selected, otherwise null is selected.
+ *
+ * If an old-style library is detected, we assume that the library is suitable + * for the current architecture and the libFolder parameter is used.
+ * + * @param libFolder + * @param arch + * Currently selected architecture + * @return + */ + static public Library fromFolder(File libFolder, String arch) { + // A library is considered "new" if it contains a file called + // "library.properties" + File libraryPropFile = new File(libFolder, "library.properties"); + if (!libraryPropFile.exists() || !libraryPropFile.isFile()) { + // construct an old style library + Library res = new Library(); + res.folder = libFolder; + res.name = libFolder.getName(); + res.oldLib = true; + return res; + } + + // Search for a subfolder for actual architecture, return null if not found + File archSubfolder = new File(libFolder, arch); + if (!archSubfolder.exists() || !archSubfolder.isDirectory()) + return null; + + Library res = new Library(); + res.folder = archSubfolder; + res.name = libFolder.getName(); + res.oldLib = false; + return res; + } + + public File getRootFolder() { + return folder; + } + + public String getName() { + return name; + } + + public void setName(String _name) { + name = _name; + } + + public static final Comparator CASE_INSENSITIVE_ORDER = new Comparator() { + @Override + public int compare(Library o1, Library o2) { + return o1.getName().compareToIgnoreCase(o2.getName()); + } + }; + + public boolean isOldLib() { + return oldLib; + } + + public boolean isNewLib() { + return !oldLib; + } + +} diff --git a/app/src/processing/app/packages/LibraryList.java b/app/src/processing/app/packages/LibraryList.java new file mode 100644 index 000000000..94fe5089e --- /dev/null +++ b/app/src/processing/app/packages/LibraryList.java @@ -0,0 +1,30 @@ +package processing.app.packages; + +import java.util.ArrayList; + +@SuppressWarnings("serial") +public class LibraryList extends ArrayList { + + public LibraryList(LibraryList libs) { + super(libs); + } + + public LibraryList() { + super(); + } + + public Library getByName(String name) { + for (Library l : this) + if (l.getName().equals(name)) + return l; + return null; + } + + public void addOrReplace(Library lib) { + Library l = getByName(lib.getName()); + if (l != null) + remove(l); + add(lib); + } + +} diff --git a/app/src/processing/app/syntax/PdeKeywords.java b/app/src/processing/app/syntax/PdeKeywords.java index 3f3016dde..4b8d8dfbe 100644 --- a/app/src/processing/app/syntax/PdeKeywords.java +++ b/app/src/processing/app/syntax/PdeKeywords.java @@ -25,6 +25,7 @@ package processing.app.syntax; import processing.app.*; +import processing.app.packages.Library; import java.io.*; import java.util.*; @@ -59,8 +60,8 @@ public class PdeKeywords extends CTokenMarker { keywordColoring = new KeywordMap(false); keywordToReference = new Hashtable(); getKeywords(Base.getLibStream("keywords.txt")); - for (File lib : Base.getLibraries().values()) { - File keywords = new File(lib, "keywords.txt"); + for (Library lib : Base.getLibraries()) { + File keywords = new File(lib.getRootFolder(), "keywords.txt"); if (keywords.exists()) getKeywords(new FileInputStream(keywords)); } } catch (Exception e) { From aa2d0e0c3cae5e3356a5d5d6d89f4e09b88a6c11 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 11 Feb 2013 18:11:52 +0100 Subject: [PATCH 4/8] Factoring Library class, step 2: first try parsing library metadata --- app/src/processing/app/Base.java | 97 ++++++------- app/src/processing/app/Sketch.java | 23 +--- app/src/processing/app/debug/Compiler.java | 10 +- .../app/helpers/StringMatchers.java | 21 +++ app/src/processing/app/packages/Library.java | 127 +++++++++++++----- .../processing/app/packages/LibraryList.java | 40 ++++++ .../processing/app/syntax/PdeKeywords.java | 2 +- 7 files changed, 207 insertions(+), 113 deletions(-) create mode 100644 app/src/processing/app/helpers/StringMatchers.java diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index 183cd6484..ef17d0ffe 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1044,25 +1044,17 @@ public class Base { } public LibraryList getIDELibs() { - LibraryList libs = new LibraryList(); if (libraries == null) - return libs; - for (Library lib : libraries) { - if (!FileUtils.isSubDirectory(getSketchbookFolder(), lib.getRootFolder())) - libs.add(lib); - } - return libs; + return new LibraryList(); + LibraryList res = new LibraryList(libraries); + res.removeAll(getUserLibs()); + return res; } public LibraryList getUserLibs() { - LibraryList libs = new LibraryList(); if (libraries == null) - return libs; - for (Library lib : libraries) { - if (FileUtils.isSubDirectory(getSketchbookFolder(), lib.getRootFolder())) - libs.add(lib); - } - return libs; + return new LibraryList(); + return libraries.filterLibrariesInSubfolder(getSketchbookFolder()); } public void rebuildImportMenu(JMenu importMenu, final Editor editor) { @@ -1124,28 +1116,16 @@ public class Base { // Add examples from libraries LibraryList ideLibs = getIDELibs(); - Collections.sort(ideLibs, Library.CASE_INSENSITIVE_ORDER); - for (Library lib : ideLibs) { - File folder = lib.getRootFolder(); - String name = lib.getName(); - addSketchesSubmenu(menu, name, folder, false); - // Allows "fat" libraries to have examples in the root folder - if (folder.getName().equals(Base.getTargetPlatform().getName())) - addSketchesSubmenu(menu, name, folder.getParentFile(), false); - } + ideLibs.sort(); + for (Library lib : ideLibs) + addSketchesSubmenu(menu, lib, false); LibraryList userLibs = getUserLibs(); if (userLibs.size()>0) { menu.addSeparator(); - Collections.sort(userLibs, Library.CASE_INSENSITIVE_ORDER); - for (Library lib : userLibs) { - File folder = lib.getRootFolder(); - String name = lib.getName(); - addSketchesSubmenu(menu, name, folder, false); - // Allows "fat" libraries to have examples in the root folder - if (folder.getName().equals(Base.getTargetPlatform().getName())) - addSketchesSubmenu(menu, name, folder.getParentFile(), false); - } + userLibs.sort(); + for (Library lib : userLibs) + addSketchesSubmenu(menu, lib, false); } } catch (IOException e) { e.printStackTrace(); @@ -1155,7 +1135,7 @@ public class Base { public LibraryList scanLibraries(List folders) { LibraryList res = new LibraryList(); for (File folder : folders) - res.addAll(scanLibraries(folder)); + res.addOrReplaceAll(scanLibraries(folder)); return res; } @@ -1178,8 +1158,7 @@ public class Base { continue; } - Library lib = Library.fromFolder(subfolder, Base.getTargetPlatform().getName()); - + Library lib = Library.create(subfolder); // (also replace previously found libs with the same name) if (lib != null) res.addOrReplace(lib); @@ -1206,18 +1185,20 @@ public class Base { // Libraries located in the latest folders on the list can override // other libraries with the same name. libraries = scanLibraries(librariesFolders); - + String currentArch = Base.getTargetPlatform().getName(); + libraries = libraries.filterByArchitecture(currentArch); + // Populate importToLibraryTable importToLibraryTable = new HashMap(); for (Library lib : libraries) { try { - String headers[] = headerListFromIncludePath(lib.getRootFolder()); + String headers[] = headerListFromIncludePath(lib.getSrcFolder()); for (String header : headers) { importToLibraryTable.put(header, lib); } } catch (IOException e) { showWarning(_("Error"), I18n - .format("Unable to list header files in {0}", lib.getRootFolder()), e); + .format("Unable to list header files in {0}", lib.getSrcFolder()), e); } } @@ -1495,6 +1476,13 @@ public class Base { return ifound; // actually ignored, but.. } + private boolean addSketchesSubmenu(JMenu menu, Library lib, + boolean replaceExisting) + throws IOException { + return addSketchesSubmenu(menu, lib.getName(), lib.getFolder(), + replaceExisting); + } + private boolean addSketchesSubmenu(JMenu menu, String name, File folder, final boolean replaceExisting) throws IOException { @@ -1564,26 +1552,25 @@ public class Base { protected void addLibraries(JMenu menu, LibraryList libs) throws IOException { LibraryList list = new LibraryList(libs); - Collections.sort(list, Library.CASE_INSENSITIVE_ORDER); - - ActionListener listener = new ActionListener() { - public void actionPerformed(ActionEvent event) { - String jarPath = event.getActionCommand(); - try { - activeEditor.getSketch().importLibrary(jarPath); - } catch (IOException e) { - showWarning(_("Error"), I18n.format("Unable to list header files in {0}", jarPath), e); - } - } - }; + list.sort(); for (Library lib : list) { - File folder = lib.getRootFolder(); - + @SuppressWarnings("serial") + AbstractAction action = new AbstractAction(lib.getName()) { + public void actionPerformed(ActionEvent event) { + Library l = (Library) getValue("library"); + try { + activeEditor.getSketch().importLibrary(l); + } catch (IOException e) { + showWarning(_("Error"), I18n.format("Unable to list header files in {0}", l.getSrcFolder()), e); + } + } + }; + action.putValue("library", lib); + // Add new element at the bottom - JMenuItem item = new JMenuItem(lib.getName()); - item.addActionListener(listener); - item.setActionCommand(folder.getAbsolutePath()); + JMenuItem item = new JMenuItem(action); + item.putClientProperty("library", lib); menu.add(item); // XXX: DAM: should recurse here so that library folders can be nested diff --git a/app/src/processing/app/Sketch.java b/app/src/processing/app/Sketch.java index df09bab1a..fe65a9761 100644 --- a/app/src/processing/app/Sketch.java +++ b/app/src/processing/app/Sketch.java @@ -89,12 +89,6 @@ public class Sketch { /** Class path determined during build. */ private String classPath; - /** - * This is *not* the "Processing" libraries path, this is the Java libraries - * path, as in java.library.path=BlahBlah, which identifies search paths for - * DLLs or JNILIBs. - */ - private String libraryPath; /** * List of library folders. */ @@ -1122,15 +1116,19 @@ public class Sketch { } + public void importLibrary(Library lib) throws IOException { + importLibrary(lib.getSrcFolder()); + } + /** * Add import statements to the current tab for all of packages inside * the specified jar file. */ - public void importLibrary(String jarPath) throws IOException { + public void importLibrary(File jarPath) throws IOException { // make sure the user didn't hide the sketch folder ensureExistence(); - String list[] = Base.headerListFromIncludePath(new File(jarPath)); + String list[] = Base.headerListFromIncludePath(jarPath); // import statements into the main sketch file (code[0]) // if the current code is a .java file, insert into current @@ -1424,8 +1422,6 @@ public class Sketch { // grab the imports from the code just preproc'd importedLibraries = new LibraryList(); - //Remember to clear library path before building it. - libraryPath = ""; for (String item : preprocessor.getExtraImports()) { Library lib = Base.importToLibraryTable.get(item); @@ -1433,8 +1429,6 @@ public class Sketch { if (lib != null && !importedLibraries.contains(lib)) { importedLibraries.add(lib); - //classPath += Compiler.contentsToClassPath(libFolder); - libraryPath += File.pathSeparator + lib.getRootFolder().getAbsolutePath(); } } @@ -1889,11 +1883,6 @@ public class Sketch { } - public String getLibraryPath() { - return libraryPath; - } - - public SketchCode[] getCode() { return code; } diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index ebb997116..c1e94bee4 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -86,7 +86,7 @@ public class Compiler implements MessageConsumer { if (prefs.get("build.variant.path").length() != 0) includePaths.add(prefs.get("build.variant.path")); for (Library lib : sketch.getImportedLibraries()) - includePaths.add(lib.getRootFolder().getPath()); + includePaths.add(lib.getSrcFolder().getPath()); // 1. compile the sketch (already in the buildPath) sketch.setCompilingProgress(30); @@ -582,11 +582,11 @@ public class Compiler implements MessageConsumer { void compileLibraries(List includePaths) throws RunnerException { File outputPath = new File(prefs.get("build.path")); for (Library lib : sketch.getImportedLibraries()) { - File libFolder = lib.getRootFolder(); - if (lib.isNewLib()) { - recursiveCompileLibrary(outputPath, libFolder, includePaths); - } else { + File libFolder = lib.getSrcFolder(); + if (lib.isPre15Lib()) { compileLibrary(outputPath, libFolder, includePaths); + } else { + recursiveCompileLibrary(outputPath, libFolder, includePaths); } } } diff --git a/app/src/processing/app/helpers/StringMatchers.java b/app/src/processing/app/helpers/StringMatchers.java new file mode 100644 index 000000000..686d9b2ab --- /dev/null +++ b/app/src/processing/app/helpers/StringMatchers.java @@ -0,0 +1,21 @@ +package processing.app.helpers; + +public class StringMatchers { + + /** + * Tries to match input with pattern. The pattern can use the + * "*" and "?" globs to match any-char-sequence and any-char respectively. + * + * @param input + * The string to be checked + * @param pattern + * The pattern to match + * @return true if the input matches the pattern, + * false otherwise. + */ + public static boolean wildcardMatch(String input, String pattern) { + String regex = pattern.replace("?", ".?").replace("*", ".*?"); + return input.matches(regex); + } + +} diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index 27f72254b..f795a1f8b 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -1,64 +1,114 @@ package processing.app.packages; +import static processing.app.helpers.StringMatchers.wildcardMatch; + import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Comparator; import java.util.List; +import processing.app.helpers.PreferencesMap; + public class Library { private String name; - private File folder; + private String version; + private File folder, srcFolder; private List architectures; - private boolean oldLib = true; + private boolean pre15Lib; /** - * Scans inside a library folder to see if it contains a version suitable for - * the actual selected architecture. If a suitable version is found the folder - * containing that version is selected, otherwise null is selected.
- *
- * If an old-style library is detected, we assume that the library is suitable - * for the current architecture and the libFolder parameter is used.
+ * Scans inside a folder and create a Library object out of it. Automatically + * detects pre-1.5 libraries. Automatically fills metadata from + * library.properties file if found. * * @param libFolder - * @param arch - * Currently selected architecture * @return */ - static public Library fromFolder(File libFolder, String arch) { + static public Library create(File libFolder) { // A library is considered "new" if it contains a file called // "library.properties" - File libraryPropFile = new File(libFolder, "library.properties"); - if (!libraryPropFile.exists() || !libraryPropFile.isFile()) { - // construct an old style library - Library res = new Library(); - res.folder = libFolder; - res.name = libFolder.getName(); - res.oldLib = true; - return res; + File check = new File(libFolder, "library.properties"); + if (!check.exists() || !check.isFile()) + return createPre15Library(libFolder); + else + return createLibrary(libFolder); + } + + private static Library createLibrary(File libFolder) { + // Parse metadata + File propertiesFile = new File(libFolder, "library.properties"); + PreferencesMap properties = new PreferencesMap(); + try { + properties.load(propertiesFile); + } catch (IOException e) { + e.printStackTrace(); + return null; } - // Search for a subfolder for actual architecture, return null if not found - File archSubfolder = new File(libFolder, arch); - if (!archSubfolder.exists() || !archSubfolder.isDirectory()) + // Library sanity checks + // --------------------- + + // 1. Check mandatory properties + if (!properties.containsKey("name")) + return null; + if (!properties.containsKey("version")) + return null; + if (!properties.containsKey("architectures")) return null; + // 2. Check mandatory folders + File srcFolder = new File(libFolder, "src"); + if (!srcFolder.exists() && !srcFolder.isDirectory()) + return null; + + // TODO: 3. check if root folder contains prohibited stuff + + // Extract metadata info + // TODO: do for all metadata + List archs = new ArrayList(); + for (String arch : properties.get("architectures").split(",")) + archs.add(arch.trim()); + Library res = new Library(); - res.folder = archSubfolder; - res.name = libFolder.getName(); - res.oldLib = false; + res.folder = libFolder; + res.srcFolder = srcFolder; + res.name = properties.get("name").trim(); + res.architectures = archs; + res.version = properties.get("version").trim(); + res.pre15Lib = false; return res; } - public File getRootFolder() { - return folder; + private static Library createPre15Library(File libFolder) { + // construct an old style library + Library res = new Library(); + res.folder = libFolder; + res.srcFolder = libFolder; + res.name = libFolder.getName(); + res.architectures = Arrays.asList(new String[] { "*" }); + res.pre15Lib = true; + return res; } - public String getName() { - return name; + public List getSrcFolders(String reqArch) { + if (!supportsArchitecture(reqArch)) + return null; + List res = new ArrayList(); + res.add(srcFolder); + File archSpecificFolder = new File(srcFolder, reqArch); + if (archSpecificFolder.exists() && archSpecificFolder.isDirectory()) + res.add(archSpecificFolder); + return res; } - public void setName(String _name) { - name = _name; + public boolean supportsArchitecture(String reqArch) { + for (String arch : architectures) + if (wildcardMatch(reqArch, arch)) + return true; + return false; } public static final Comparator CASE_INSENSITIVE_ORDER = new Comparator() { @@ -68,12 +118,19 @@ public class Library { } }; - public boolean isOldLib() { - return oldLib; + public File getSrcFolder() { + return srcFolder; } - public boolean isNewLib() { - return !oldLib; + public String getName() { + return name; } + public boolean isPre15Lib() { + return pre15Lib; + } + + public File getFolder() { + return folder; + } } diff --git a/app/src/processing/app/packages/LibraryList.java b/app/src/processing/app/packages/LibraryList.java index 94fe5089e..343ff4bde 100644 --- a/app/src/processing/app/packages/LibraryList.java +++ b/app/src/processing/app/packages/LibraryList.java @@ -1,6 +1,11 @@ package processing.app.packages; +import java.io.File; import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; + +import processing.app.helpers.FileUtils; @SuppressWarnings("serial") public class LibraryList extends ArrayList { @@ -27,4 +32,39 @@ public class LibraryList extends ArrayList { add(lib); } + public void addOrReplaceAll(Collection c) { + for (Library l : c) + addOrReplace(l); + } + + public void sort() { + Collections.sort(this, Library.CASE_INSENSITIVE_ORDER); + } + + public Library search(String name, String arch) { + for (Library lib : this) { + if (!lib.getName().equals(name)) + continue; + if (!lib.supportsArchitecture(arch)) + continue; + return lib; + } + return null; + } + + public LibraryList filterByArchitecture(String reqArch) { + LibraryList res = new LibraryList(); + for (Library lib : this) + if (lib.supportsArchitecture(reqArch)) + res.add(lib); + return res; + } + + public LibraryList filterLibrariesInSubfolder(File subFolder) { + LibraryList res = new LibraryList(); + for (Library lib : this) + if (FileUtils.isSubDirectory(subFolder, lib.getFolder())) + res.add(lib); + return res; + } } diff --git a/app/src/processing/app/syntax/PdeKeywords.java b/app/src/processing/app/syntax/PdeKeywords.java index 4b8d8dfbe..701978a45 100644 --- a/app/src/processing/app/syntax/PdeKeywords.java +++ b/app/src/processing/app/syntax/PdeKeywords.java @@ -61,7 +61,7 @@ public class PdeKeywords extends CTokenMarker { keywordToReference = new Hashtable(); getKeywords(Base.getLibStream("keywords.txt")); for (Library lib : Base.getLibraries()) { - File keywords = new File(lib.getRootFolder(), "keywords.txt"); + File keywords = new File(lib.getFolder(), "keywords.txt"); if (keywords.exists()) getKeywords(new FileInputStream(keywords)); } } catch (Exception e) { From e5fa7e8183f1ea29d43c72c79bcf1d1efb8f3972 Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Mon, 11 Feb 2013 19:31:39 +0100 Subject: [PATCH 5/8] BOARDS and ARCH defines from boards.txt See #308 --- app/src/processing/app/debug/Compiler.java | 1 + hardware/arduino/avr/boards.txt | 16 ++++++++++++++++ hardware/arduino/avr/platform.txt | 4 ++-- hardware/arduino/sam/boards.txt | 2 ++ hardware/arduino/sam/platform.txt | 4 ++-- 5 files changed, 23 insertions(+), 4 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 1bd8b8c25..26597116a 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -142,6 +142,7 @@ public class Compiler implements MessageConsumer { p.put("build.path", _buildPath); p.put("build.project_name", _primaryClassName); + p.put("build.arch", targetPlatform.getName().toUpperCase()); if (!p.containsKey("compiler.path")) p.put("compiler.path", Base.getAvrBasePath()); diff --git a/hardware/arduino/avr/boards.txt b/hardware/arduino/avr/boards.txt index 137211363..d9860e6c3 100644 --- a/hardware/arduino/avr/boards.txt +++ b/hardware/arduino/avr/boards.txt @@ -20,6 +20,7 @@ uno.bootloader.file=optiboot/optiboot_atmega328.hex uno.build.mcu=atmega328p uno.build.f_cpu=16000000L +uno.build.board=ARDUINO_UNO uno.build.core=arduino uno.build.variant=standard @@ -36,6 +37,7 @@ atmega328diecimila.bootloader.unlock_bits=0x3F atmega328diecimila.bootloader.lock_bits=0x0F atmega328diecimila.build.f_cpu=16000000L +atmega328diecimila.build.board=ARDUINO_DUEMILANOVE atmega328diecimila.build.core=arduino atmega328diecimila.build.variant=standard @@ -75,6 +77,7 @@ nano.bootloader.unlock_bits=0x3F nano.bootloader.lock_bits=0x0F nano.build.f_cpu=16000000L +nano.build.board=ARDUINO_NANO nano.build.core=arduino nano.build.variant=eightanaloginputs @@ -124,6 +127,7 @@ mega2560.bootloader.lock_bits=0x0F mega2560.build.mcu=atmega2560 mega2560.build.f_cpu=16000000L +mega2560.build.board=ARDUINO_MEGA2560 mega2560.build.core=arduino mega2560.build.variant=mega @@ -147,6 +151,7 @@ mega.bootloader.lock_bits=0x0F mega.build.mcu=atmega1280 mega.build.f_cpu=16000000L +mega.build.board=ARDUINO_MEGA mega.build.core=arduino mega.build.variant=mega @@ -173,6 +178,7 @@ leonardo.build.mcu=atmega32u4 leonardo.build.f_cpu=16000000L leonardo.build.vid=0x2341 leonardo.build.pid=0x8036 +leonardo.build.board=ARDUINO_LEONARDO leonardo.build.core=arduino leonardo.build.variant=leonardo leonardo.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} @@ -200,6 +206,7 @@ micro.build.mcu=atmega32u4 micro.build.f_cpu=16000000L micro.build.vid=0x2341 micro.build.pid=0x8037 +micro.build.board=ARDUINO_MICRO micro.build.core=arduino micro.build.variant=micro micro.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} @@ -227,6 +234,7 @@ esplora.build.mcu=atmega32u4 esplora.build.f_cpu=16000000L esplora.build.vid=0x2341 esplora.build.pid=0x8036 +esplora.build.board=ARDUINO_ESPLORA esplora.build.core=arduino esplora.build.variant=leonardo esplora.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} @@ -244,6 +252,7 @@ mini.bootloader.unlock_bits=0x3F mini.bootloader.lock_bits=0x0F mini.build.f_cpu=16000000L +mini.build.board=ARDUINO_MINI mini.build.core=arduino mini.build.variant=eightanaloginputs @@ -291,6 +300,7 @@ ethernet.bootloader.lock_bits=0x0F ethernet.build.variant=standard ethernet.build.mcu=atmega328p ethernet.build.f_cpu=16000000L +ethernet.build.board=ARDUINO_ETHERNET ethernet.build.core=arduino ############################################################## @@ -312,6 +322,7 @@ fio.bootloader.lock_bits=0x0F fio.build.mcu=atmega328p fio.build.f_cpu=8000000L +fio.build.board=ARDUINO_FIO fio.build.core=arduino fio.build.variant=eightanaloginputs @@ -330,6 +341,7 @@ bt.bootloader.unlock_bits=0x3F bt.bootloader.lock_bits=0x0F bt.build.f_cpu=16000000L +bt.build.board=ARDUINO_BT bt.build.core=arduino bt.build.variant=eightanaloginputs @@ -377,6 +389,7 @@ LilyPadUSB.build.mcu=atmega32u4 LilyPadUSB.build.f_cpu=8000000L LilyPadUSB.build.vid=0x1B4F LilyPadUSB.build.pid=0x9208 +LilyPadUSB.build.board=ARDUINO_LILYPAD_USB LilyPadUSB.build.core=arduino LilyPadUSB.build.variant=leonardo LilyPadUSB.build.extra_flags=-DUSB_VID={build.vid} -DUSB_PID={build.pid} @@ -393,6 +406,7 @@ lilypad.bootloader.unlock_bits=0x3F lilypad.bootloader.lock_bits=0x0F lilypad.build.f_cpu=8000000L +lilypad.build.board=ARDUINO_LILYPAD lilypad.build.core=arduino lilypad.build.variant=standard @@ -433,6 +447,7 @@ pro.bootloader.tool=avrdude pro.bootloader.unlock_bits=0x3F pro.bootloader.lock_bits=0x0F +pro.build.board=ARDUINO_PRO pro.build.core=arduino pro.build.variant=standard @@ -506,6 +521,7 @@ atmegang.bootloader.lock_bits=0x0F atmegang.build.mcu=atmegang atmegang.build.f_cpu=16000000L +atmegang.build.board=ARDUINO_NG atmegang.build.core=arduino atmegang.build.variant=standard diff --git a/hardware/arduino/avr/platform.txt b/hardware/arduino/avr/platform.txt index d439ddd5c..a6cd314c1 100644 --- a/hardware/arduino/avr/platform.txt +++ b/hardware/arduino/avr/platform.txt @@ -27,10 +27,10 @@ build.extra_flags= # -------------------- ## Compile c files -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} -D{build.board} -DARDUINO_ARCH_{build.arch} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" ## Compile c++ files -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} -D{build.board} -DARDUINO_ARCH_{build.arch} {build.extra_flags} {includes} "{source_file}" -o "{object_file}" ## Create archives recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}" diff --git a/hardware/arduino/sam/boards.txt b/hardware/arduino/sam/boards.txt index 5d6f386cd..d3629e596 100644 --- a/hardware/arduino/sam/boards.txt +++ b/hardware/arduino/sam/boards.txt @@ -8,6 +8,7 @@ arduino_due_x_dbg.upload.wait_for_upload_port=false arduino_due_x_dbg.upload.native_usb=false arduino_due_x_dbg.build.mcu=cortex-m3 arduino_due_x_dbg.build.f_cpu=84000000L +arduino_due_x_dbg.build.board=ARDUINO_DUE arduino_due_x_dbg.build.core=arduino arduino_due_x_dbg.build.extra_flags=-D__SAM3X8E__ -mthumb -DUSB_PID={build.pid} -DUSB_VID={build.vid} -DUSBCON arduino_due_x_dbg.build.ldscript=linker_scripts/gcc/flash.ld @@ -25,6 +26,7 @@ arduino_due_x.upload.wait_for_upload_port=true arduino_due_x.upload.native_usb=true arduino_due_x.build.mcu=cortex-m3 arduino_due_x.build.f_cpu=84000000L +arduino_due_x.build.board=ARDUINO_DUE arduino_due_x.build.core=arduino arduino_due_x.build.extra_flags=-D__SAM3X8E__ -mthumb -DUSB_PID={build.pid} -DUSB_VID={build.vid} -DUSBCON arduino_due_x.build.ldscript=linker_scripts/gcc/flash.ld diff --git a/hardware/arduino/sam/platform.txt b/hardware/arduino/sam/platform.txt index fedb29e12..3594610ea 100644 --- a/hardware/arduino/sam/platform.txt +++ b/hardware/arduino/sam/platform.txt @@ -30,10 +30,10 @@ compiler.libsam.c.flags="-I{build.system.path}/libsam" "-I{build.system.path}/CM # --------------------- ## Compile c files -recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.c.o.pattern="{compiler.path}{compiler.c.cmd}" {compiler.c.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} -D{build.board} -DARDUINO_ARCH_{build.arch} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}" ## Compile c++ files -recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}" +recipe.cpp.o.pattern="{compiler.path}{compiler.cpp.cmd}" {compiler.cpp.flags} -mcpu={build.mcu} -DF_CPU={build.f_cpu} -D{software}={runtime.ide.version} -D{build.board} -DARDUINO_ARCH_{build.arch} {build.extra_flags} {compiler.libsam.c.flags} {includes} "{source_file}" -o "{object_file}" ## Create archives recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags} "{build.path}/{archive_file}" "{object_file}" From bddb47ed26af6a8da8e76c512374ec61eb1ef4eb Mon Sep 17 00:00:00 2001 From: Cristian Maglie Date: Wed, 13 Feb 2013 19:10:30 +0100 Subject: [PATCH 6/8] Library class, round 2 --- app/src/processing/app/debug/Compiler.java | 22 ++-- app/src/processing/app/packages/Library.java | 126 ++++++++++++++++--- 2 files changed, 122 insertions(+), 26 deletions(-) diff --git a/app/src/processing/app/debug/Compiler.java b/app/src/processing/app/debug/Compiler.java index 119c846a9..80cbe9ed6 100644 --- a/app/src/processing/app/debug/Compiler.java +++ b/app/src/processing/app/debug/Compiler.java @@ -57,7 +57,8 @@ public class Compiler implements MessageConsumer { private PreferencesMap prefs; private boolean verbose; private boolean sketchIsCompiled; - + private String targetArch; + private RunnerException exception; /** @@ -86,7 +87,8 @@ public class Compiler implements MessageConsumer { if (prefs.get("build.variant.path").length() != 0) includePaths.add(prefs.get("build.variant.path")); for (Library lib : sketch.getImportedLibraries()) - includePaths.add(lib.getSrcFolder().getPath()); + for (File folder : lib.getSrcFolders(targetArch)) + includePaths.add(folder.getPath()); // 1. compile the sketch (already in the buildPath) sketch.setCompilingProgress(30); @@ -131,7 +133,7 @@ public class Compiler implements MessageConsumer { } TargetPlatform targetPlatform = Base.getTargetPlatform(); - + // Merge all the global preference configuration in order of priority PreferencesMap p = new PreferencesMap(); p.putAll(Preferences.getMap()); @@ -144,7 +146,8 @@ public class Compiler implements MessageConsumer { p.put("build.path", _buildPath); p.put("build.project_name", _primaryClassName); - p.put("build.arch", targetPlatform.getName().toUpperCase()); + targetArch = targetPlatform.getName(); + p.put("build.arch", targetArch.toUpperCase()); if (!p.containsKey("compiler.path")) p.put("compiler.path", Base.getAvrBasePath()); @@ -583,11 +586,12 @@ public class Compiler implements MessageConsumer { void compileLibraries(List includePaths) throws RunnerException { File outputPath = new File(prefs.get("build.path")); for (Library lib : sketch.getImportedLibraries()) { - File libFolder = lib.getSrcFolder(); - if (lib.isPre15Lib()) { - compileLibrary(outputPath, libFolder, includePaths); - } else { - recursiveCompileLibrary(outputPath, libFolder, includePaths); + for (File folder : lib.getSrcFolders(targetArch)) { + if (lib.isPre15Lib()) { + compileLibrary(outputPath, folder, includePaths); + } else { + recursiveCompileLibrary(outputPath, folder, includePaths); + } } } } diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index f795a1f8b..a01200f7c 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -15,10 +15,26 @@ public class Library { private String name; private String version; - private File folder, srcFolder; + private String author; + private String email; + private String url; + private String sentence; + private String paragraph; + private List coreDependencies; + private List dependencies; + private File folder, srcFolder, archFolder; private List architectures; private boolean pre15Lib; + private static final List MANDATORY_PROPERTIES = Arrays + .asList(new String[] { "architectures", "author", "core-dependencies", + "dependencies", "email", "name", "paragraph", "sentence", "url", + "version" }); + private static final List OPTIONAL_FOLDERS = Arrays + .asList(new String[] { "arch", "examples", "extras", "src" }); + private static final List OPTIONAL_FILES = Arrays + .asList(new String[] { "keywords.txt", "library.properties" }); + /** * Scans inside a folder and create a Library object out of it. Automatically * detects pre-1.5 libraries. Automatically fills metadata from @@ -52,31 +68,49 @@ public class Library { // --------------------- // 1. Check mandatory properties - if (!properties.containsKey("name")) - return null; - if (!properties.containsKey("version")) - return null; - if (!properties.containsKey("architectures")) - return null; + for (String p : MANDATORY_PROPERTIES) + if (!properties.containsKey(p)) + return null; // 2. Check mandatory folders File srcFolder = new File(libFolder, "src"); if (!srcFolder.exists() && !srcFolder.isDirectory()) return null; - - // TODO: 3. check if root folder contains prohibited stuff - - // Extract metadata info - // TODO: do for all metadata - List archs = new ArrayList(); - for (String arch : properties.get("architectures").split(",")) - archs.add(arch.trim()); + // 3. check if root folder contains prohibited stuff + for (File file : libFolder.listFiles()) { + if (file.isDirectory()) { + if (!OPTIONAL_FOLDERS.contains(file.getName())) + return null; + } else { + if (!OPTIONAL_FILES.contains(file.getName())) + return null; + } + } + + // Extract metadata info Library res = new Library(); res.folder = libFolder; res.srcFolder = srcFolder; + res.archFolder = new File(libFolder, "arch"); res.name = properties.get("name").trim(); + res.author = properties.get("author").trim(); + res.email = properties.get("email").trim(); + res.sentence = properties.get("sentence").trim(); + res.paragraph = properties.get("paragraph").trim(); + res.url = properties.get("url").trim(); + List archs = new ArrayList(); + for (String arch : properties.get("architectures").split(",")) + archs.add(arch.trim()); res.architectures = archs; + List deps = new ArrayList(); + for (String dep : properties.get("dependencies").split(",")) + deps.add(dep.trim()); + res.dependencies = deps; + List coreDeps = new ArrayList(); + for (String dep : properties.get("core-dependencies").split(",")) + coreDeps.add(dep.trim()); + res.coreDependencies = coreDeps; res.version = properties.get("version").trim(); res.pre15Lib = false; return res; @@ -98,9 +132,15 @@ public class Library { return null; List res = new ArrayList(); res.add(srcFolder); - File archSpecificFolder = new File(srcFolder, reqArch); - if (archSpecificFolder.exists() && archSpecificFolder.isDirectory()) + File archSpecificFolder = new File(archFolder, reqArch); + if (archSpecificFolder.exists() && archSpecificFolder.isDirectory()) { res.add(archSpecificFolder); + } else { + // If specific architecture folder is not found try with "default" + archSpecificFolder = new File(archFolder, "default"); + if (archSpecificFolder.exists() && archSpecificFolder.isDirectory()) + res.add(archSpecificFolder); + } return res; } @@ -133,4 +173,56 @@ public class Library { public File getFolder() { return folder; } + + public List getArchitectures() { + return architectures; + } + + public String getAuthor() { + return author; + } + + public List getCoreDependencies() { + return coreDependencies; + } + + public List getDependencies() { + return dependencies; + } + + public String getEmail() { + return email; + } + + public String getParagraph() { + return paragraph; + } + + public String getSentence() { + return sentence; + } + + public String getUrl() { + return url; + } + + public String getVersion() { + return version; + } + + @Override + public String toString() { + String res = "Library:"; + res += " (name=" + name + ")"; + res += " (architectures=" + architectures + ")"; + res += " (author=" + author + ")"; + res += " (core-dependencies=" + coreDependencies + ")"; + res += " (dependencies=" + dependencies + ")"; + res += " (email=" + email + ")"; + res += " (paragraph=" + paragraph + ")"; + res += " (sentence=" + sentence + ")"; + res += " (url=" + url + ")"; + res += " (version=" + version + ")"; + return res; + } } From 2a051a76a70cd3f2581567ac765a02e0a8297549 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 19 Feb 2013 12:09:57 +0100 Subject: [PATCH 7/8] Library: converted nulls to checked exceptions, removed printStackTrace, added "dependencies" member Conflicts: app/src/processing/app/packages/Library.java --- app/src/processing/app/packages/Library.java | 56 ++++++++++---------- 1 file changed, 29 insertions(+), 27 deletions(-) diff --git a/app/src/processing/app/packages/Library.java b/app/src/processing/app/packages/Library.java index a01200f7c..6779c88e8 100644 --- a/app/src/processing/app/packages/Library.java +++ b/app/src/processing/app/packages/Library.java @@ -1,6 +1,6 @@ package processing.app.packages; -import static processing.app.helpers.StringMatchers.wildcardMatch; +import processing.app.helpers.PreferencesMap; import java.io.File; import java.io.IOException; @@ -9,7 +9,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; -import processing.app.helpers.PreferencesMap; +import static processing.app.helpers.StringMatchers.wildcardMatch; public class Library { @@ -39,11 +39,11 @@ public class Library { * Scans inside a folder and create a Library object out of it. Automatically * detects pre-1.5 libraries. Automatically fills metadata from * library.properties file if found. - * + * * @param libFolder * @return */ - static public Library create(File libFolder) { + static public Library create(File libFolder) throws IOException { // A library is considered "new" if it contains a file called // "library.properties" File check = new File(libFolder, "library.properties"); @@ -53,16 +53,11 @@ public class Library { return createLibrary(libFolder); } - private static Library createLibrary(File libFolder) { + private static Library createLibrary(File libFolder) throws IOException { // Parse metadata File propertiesFile = new File(libFolder, "library.properties"); PreferencesMap properties = new PreferencesMap(); - try { - properties.load(propertiesFile); - } catch (IOException e) { - e.printStackTrace(); - return null; - } + properties.load(propertiesFile); // Library sanity checks // --------------------- @@ -70,25 +65,41 @@ public class Library { // 1. Check mandatory properties for (String p : MANDATORY_PROPERTIES) if (!properties.containsKey(p)) - return null; + throw new IOException("Missing '" + p + "' from library"); // 2. Check mandatory folders File srcFolder = new File(libFolder, "src"); - if (!srcFolder.exists() && !srcFolder.isDirectory()) - return null; + if (!srcFolder.exists() || !srcFolder.isDirectory()) + throw new IOException("Missing 'src' folder"); // 3. check if root folder contains prohibited stuff for (File file : libFolder.listFiles()) { if (file.isDirectory()) { if (!OPTIONAL_FOLDERS.contains(file.getName())) - return null; + throw new IOException("Invalid folder '" + file.getName() + "'."); } else { if (!OPTIONAL_FILES.contains(file.getName())) - return null; + throw new IOException("Invalid file '" + file.getName() + "'."); } } // Extract metadata info + List archs = new ArrayList(); + for (String arch : properties.get("architectures").split(",")) + archs.add(arch.trim()); + + List coreDeps = new ArrayList(); + for (String dep : properties.get("core-dependencies").split(",")) + coreDeps.add(dep.trim()); + + List dependencies = new ArrayList(); + for (String dependency : properties.get("dependencies").split(",")) { + dependency = dependency.trim(); + if (!dependency.equals("")) { + dependencies.add(dependency); + } + } + Library res = new Library(); res.folder = libFolder; res.srcFolder = srcFolder; @@ -99,18 +110,9 @@ public class Library { res.sentence = properties.get("sentence").trim(); res.paragraph = properties.get("paragraph").trim(); res.url = properties.get("url").trim(); - List archs = new ArrayList(); - for (String arch : properties.get("architectures").split(",")) - archs.add(arch.trim()); res.architectures = archs; - List deps = new ArrayList(); - for (String dep : properties.get("dependencies").split(",")) - deps.add(dep.trim()); - res.dependencies = deps; - List coreDeps = new ArrayList(); - for (String dep : properties.get("core-dependencies").split(",")) - coreDeps.add(dep.trim()); res.coreDependencies = coreDeps; + res.dependencies = dependencies; res.version = properties.get("version").trim(); res.pre15Lib = false; return res; @@ -122,7 +124,7 @@ public class Library { res.folder = libFolder; res.srcFolder = libFolder; res.name = libFolder.getName(); - res.architectures = Arrays.asList(new String[] { "*" }); + res.architectures = Arrays.asList(new String[]{"*"}); res.pre15Lib = true; return res; } From 14308c66d76924c0ae6e6d96e5c46529ac99ce82 Mon Sep 17 00:00:00 2001 From: Federico Fissore Date: Tue, 19 Feb 2013 12:10:48 +0100 Subject: [PATCH 8/8] Library: converted nulls to checked exceptions, removed printStackTrace, added "dependencies" member --- app/src/processing/app/Base.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/app/src/processing/app/Base.java b/app/src/processing/app/Base.java index a53597cab..169aba346 100644 --- a/app/src/processing/app/Base.java +++ b/app/src/processing/app/Base.java @@ -1132,14 +1132,14 @@ public class Base { } } - public LibraryList scanLibraries(List folders) { + public LibraryList scanLibraries(List folders) throws IOException { LibraryList res = new LibraryList(); for (File folder : folders) res.addOrReplaceAll(scanLibraries(folder)); return res; } - public LibraryList scanLibraries(File folder) { + public LibraryList scanLibraries(File folder) throws IOException { LibraryList res = new LibraryList(); String list[] = folder.list(new OnlyDirs()); @@ -1184,7 +1184,11 @@ public class Base { // Scan for libraries in each library folder. // Libraries located in the latest folders on the list can override // other libraries with the same name. - libraries = scanLibraries(librariesFolders); + try { + libraries = scanLibraries(librariesFolders); + } catch (IOException e) { + showWarning(_("Error"), _("Error reading preferences"), e); + } String currentArch = Base.getTargetPlatform().getName(); libraries = libraries.filterByArchitecture(currentArch);