From b5dde887ab05e50b37d790940d8598141690be12 Mon Sep 17 00:00:00 2001 From: "David A. Mellis" Date: Sun, 26 Mar 2006 22:16:55 +0000 Subject: [PATCH] Library system working: Import Library menu adds header files to sketch, linking is conditional based on #include's in sketch. --- app/Compiler.java | 31 +++++++++++-- app/Editor.java | 2 +- app/Library.java | 4 +- app/LibraryManager.java | 19 ++++++-- app/Sketch.java | 46 ++++++++++++++----- app/Sketchbook.java | 25 +++++++--- app/preproc/PdePreprocessor.java | 15 +++--- .../macosx/Arduino.xcodeproj/project.pbxproj | 8 ++-- targets/libraries/Foo/Foo.cpp | 35 ++++++++++++++ targets/libraries/Foo/Foo.h | 33 +++++++++++++ targets/libraries/{ => Matrix}/Matrix.cpp | 0 targets/libraries/{ => Matrix}/Matrix.h | 0 targets/libraries/{ => Sprite}/Sprite.cpp | 0 targets/libraries/{ => Sprite}/Sprite.h | 0 .../{arduino => libraries/Sprite}/binary.h | 0 15 files changed, 178 insertions(+), 40 deletions(-) create mode 100644 targets/libraries/Foo/Foo.cpp create mode 100644 targets/libraries/Foo/Foo.h rename targets/libraries/{ => Matrix}/Matrix.cpp (100%) rename targets/libraries/{ => Matrix}/Matrix.h (100%) rename targets/libraries/{ => Sprite}/Sprite.cpp (100%) rename targets/libraries/{ => Sprite}/Sprite.h (100%) rename targets/{arduino => libraries/Sprite}/binary.h (100%) diff --git a/app/Compiler.java b/app/Compiler.java index d7b627cc2..e30830fb0 100644 --- a/app/Compiler.java +++ b/app/Compiler.java @@ -75,8 +75,14 @@ public class Compiler implements MessageConsumer { MessageStream pms = new MessageStream(this); String userdir = System.getProperty("user.dir") + File.separator; - - LibraryManager libraryManager = new LibraryManager(); + +// LibraryManager libraryManager; +// +// try { +// libraryManager = new LibraryManager(); +// } catch (IOException e) { +// throw new RunnerException(e.getMessage()); +// } String preCommandCompiler[] = new String[] { ((!Base.isMacOS()) ? "tools/avr/bin/avr-gcc" : @@ -91,7 +97,11 @@ public class Compiler implements MessageConsumer { }; // use lib directories as include paths - String[] libDirs = libraryManager.getFolderPaths(); + //String[] libDirs = libraryManager.getFolderPaths(); + String[] libDirs = new String[sketch.importedLibraries.size()]; + + for (int i = 0; i < sketch.importedLibraries.size(); i++) + libDirs[i] = ((Library) sketch.importedLibraries.get(i)).getFolder().getPath(); // Last two arguments will specify the file being compiled and the output file. String[] baseCommandCompiler = new String[preCommandCompiler.length + libDirs.length + 2]; @@ -131,7 +141,20 @@ public class Compiler implements MessageConsumer { }; // use lib object files during include - String[] libObjectFiles = libraryManager.getObjectFiles(); + //String[] libObjectFiles = libraryManager.getObjectFiles(); + + Vector libObjectFilesVec = new Vector(); + + for (Iterator i = sketch.importedLibraries.iterator(); i.hasNext(); ) { + Library library = (Library) i.next(); + File[] objectFiles = library.getObjectFiles(); + for (int j = 0; j < objectFiles.length; j++) + libObjectFilesVec.add(objectFiles[j].getPath()); + } + + String[] libObjectFiles = new String[libObjectFilesVec.size()]; + libObjectFiles = (String[]) libObjectFilesVec.toArray(libObjectFiles); + String[] baseCommandLinker = new String[preCommandLinker.length + libObjectFiles.length]; System.arraycopy(preCommandLinker, 0, baseCommandLinker, 0, preCommandLinker.length); for (int i = 0; i < libObjectFiles.length; ++i) { diff --git a/app/Editor.java b/app/Editor.java index 09065a9a6..02c8008cf 100644 --- a/app/Editor.java +++ b/app/Editor.java @@ -613,7 +613,7 @@ public class Editor extends JFrame }); menu.add(item); - //menu.add(sketchbook.getImportMenu()); + menu.add(sketchbook.getImportMenu()); if (Base.isWindows() || Base.isMacOS()) { // no way to do an 'open in file browser' on other platforms diff --git a/app/Library.java b/app/Library.java index 4d3c6974c..794ea08a2 100755 --- a/app/Library.java +++ b/app/Library.java @@ -266,7 +266,7 @@ public class Library implements MessageConsumer{ "-Wall", "-mmcu=" + Preferences.get("build.mcu"), "-DF_CPU=" + Preferences.get("build.f_cpu"), - "-Ilib", + "-I" + libManager.getTarget().getPath(), "-I" + getFolder(), }; @@ -279,7 +279,7 @@ public class Library implements MessageConsumer{ "-fno-exceptions", "-mmcu=" + Preferences.get("build.mcu"), "-DF_CPU=" + Preferences.get("build.f_cpu"), - "-Ilib", + "-I" + libManager.getTarget().getPath(), "-I" + getFolder(), }; diff --git a/app/LibraryManager.java b/app/LibraryManager.java index f12c2ae2f..94b609123 100755 --- a/app/LibraryManager.java +++ b/app/LibraryManager.java @@ -34,18 +34,27 @@ public class LibraryManager { private File libDir; private List libraries = new ArrayList(); - + private Target target; + /* * Create a LibraryManager. */ - public LibraryManager() + public LibraryManager() throws IOException { String userDir = System.getProperty("user.dir") + File.separator; libDir = new File( ((!Base.isMacOS()) ? "" : userDir) + "lib" + File.separator + "targets" + File.separator + "libraries"); + target = new Target( + System.getProperty("user.dir") + File.separator + "lib" + + File.separator + "targets", Preferences.get("build.target")); refreshLibraries(); } + + public Target getTarget() + { + return target; + } /* * Scans for libraries and refreshes internal list @@ -159,9 +168,11 @@ public class LibraryManager { */ public String[] getFolderPaths() { ArrayList foldersArrayList = new ArrayList(); - Collection builtLibraries = getBuiltLibraries(); + //Collection builtLibraries = getBuiltLibraries(); + Collection libraries = getAll(); Library library; - Iterator libIterator = builtLibraries.iterator(); + //Iterator libIterator = builtLibraries.iterator(); + Iterator libIterator = libraries.iterator(); while(libIterator.hasNext()){ library = (Library)libIterator.next(); foldersArrayList.add(library.getFolder().getPath()); diff --git a/app/Sketch.java b/app/Sketch.java index 56f68250d..b5e9abe8b 100644 --- a/app/Sketch.java +++ b/app/Sketch.java @@ -86,7 +86,7 @@ public class Sketch { String classPath; String libraryPath; boolean externalRuntime; - Vector importedLibraries; // vec of File objects + public Vector importedLibraries; // vec of Library objects /** * path is location of the main .pde file, because this is also @@ -1126,10 +1126,17 @@ public class Sketch { public void importLibrary(String jarPath) { System.out.println(jarPath); -/* // make sure the user didn't hide the sketch folder + // make sure the user didn't hide the sketch folder ensureExistence(); - String list[] = Compiler.packageListFromClassPath(jarPath); + //String list[] = Compiler.packageListFromClassPath(jarPath); + FileFilter onlyHFiles = new FileFilter() { + public boolean accept(File file) { + return (file.getName()).endsWith(".h"); + } + }; + + File list[] = new File(jarPath).listFiles(onlyHFiles); // import statements into the main sketch file (code[0]) // if the current code is a .java file, insert into current @@ -1141,15 +1148,15 @@ public class Sketch { // commented out, then this will be a problem. StringBuffer buffer = new StringBuffer(); for (int i = 0; i < list.length; i++) { - buffer.append("import "); - buffer.append(list[i]); - buffer.append(".*;\n"); + buffer.append("#include <"); + buffer.append(list[i].getName()); + buffer.append(">\n"); } buffer.append('\n'); buffer.append(editor.getText()); editor.setText(buffer.toString(), 0, 0); // scroll to start - setModified(); -*/ } + setModified(true); + } /** @@ -1333,8 +1340,9 @@ public class Sketch { // build unbuilt buildable libraries // completely independent from sketch, so run all the time - LibraryManager libraryManager = new LibraryManager(); + LibraryManager libraryManager; try { + libraryManager = new LibraryManager(); libraryManager.buildAllUnbuilt(); } catch (RunnerException re) { throw new RunnerException(re.getMessage()); @@ -1555,7 +1563,21 @@ public class Sketch { importedLibraries = new Vector(); String imports[] = preprocessor.extraImports; - for (int i = 0; i < imports.length; i++) { + Collection libraries = libraryManager.getAll(); + for (Iterator i = libraries.iterator(); i.hasNext(); ) { + Library library = (Library) i.next(); + File[] headerFiles = library.getHeaderFiles(); + + for (int j = 0; j < headerFiles.length; j++) + for (int k = 0; k < imports.length; k++) + if (headerFiles[j].getName().equals(imports[k]) && + !importedLibraries.contains(library)) { + importedLibraries.add(library); + //System.out.println("Adding library " + library.getName()); + } + } + //for (int i = 0; i < imports.length; i++) { + /* // remove things up to the last dot String entry = imports[i].substring(0, imports[i].lastIndexOf('.')); //System.out.println("found package " + entry); @@ -1568,7 +1590,7 @@ public class Sketch { importedLibraries.add(libFolder); libraryPath += File.pathSeparator + libFolder.getAbsolutePath(); - + */ /* String list[] = libFolder.list(); if (list != null) { @@ -1582,7 +1604,7 @@ public class Sketch { } } */ - } + //} // 3. then loop over the code[] and save each .java file diff --git a/app/Sketchbook.java b/app/Sketchbook.java index 460974a4c..596d9dbaf 100644 --- a/app/Sketchbook.java +++ b/app/Sketchbook.java @@ -86,7 +86,8 @@ public class Sketchbook { examplesFolder = new File(System.getProperty("user.dir"), "examples"); examplesPath = examplesFolder.getAbsolutePath(); - librariesFolder = new File(System.getProperty("user.dir"), "libraries"); + librariesFolder = new File(System.getProperty("user.dir"), + "lib" + File.separator + "targets" + File.separator + "libraries"); librariesPath = librariesFolder.getAbsolutePath(); String sketchbookPath = Preferences.get("sketchbook.path"); @@ -341,12 +342,14 @@ public class Sketchbook { // rebuild the "import library" menu librariesClassPath = ""; importMenu.removeAll(); + /* if (addLibraries(importMenu, new File(getSketchbookPath()))) { importMenu.addSeparator(); } if (addLibraries(importMenu, examplesFolder)) { importMenu.addSeparator(); } + */ addLibraries(importMenu, librariesFolder); //System.out.println("libraries cp is now " + librariesClassPath); @@ -383,7 +386,6 @@ public class Sketchbook { e.printStackTrace(); } - LibraryManager libManager = new LibraryManager(); ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { editor.handleOpen(e.getActionCommand()); @@ -391,6 +393,7 @@ public class Sketchbook { }; try { + LibraryManager libManager = new LibraryManager(); JMenu examplesMenu = new JMenu("Examples"); addSketches(examplesMenu, examplesFolder); libManager.populateExamplesMenu(examplesMenu, listener); @@ -552,11 +555,20 @@ public class Sketchbook { File subfolder = new File(folder, list[i]); if (!subfolder.isDirectory()) continue; - File exported = new File(subfolder, "library"); - File entry = new File(exported, list[i] + ".o"); + //File exported = new File(subfolder, "library"); + //File entry = new File(exported, list[i] + ".o"); + FileFilter onlyHFiles = new FileFilter() { + public boolean accept(File file) { + return (file.getName()).endsWith(".h"); + } + }; + + // if the folder has header files + if (subfolder.listFiles(onlyHFiles).length > 0) { // if a .jar file of the same prefix as the folder exists // inside the 'library' subfolder of the sketch - if (entry.exists()) { + //if (entry.exists()) { + /* String sanityCheck = sanitizedName(list[i]); if (!sanityCheck.equals(list[i])) { String mess = @@ -566,6 +578,7 @@ public class Sketchbook { Base.showMessage("Ignoring bad sketch name", mess); continue; } + */ /* // get the path for all .jar files in this code folder String libraryClassPath = @@ -583,7 +596,7 @@ public class Sketchbook { */ JMenuItem item = new JMenuItem(list[i]); item.addActionListener(listener); - item.setActionCommand(entry.getAbsolutePath()); + item.setActionCommand(subfolder.getAbsolutePath()); menu.add(item); ifound = true; diff --git a/app/preproc/PdePreprocessor.java b/app/preproc/PdePreprocessor.java index 97d95a802..e0b713f88 100755 --- a/app/preproc/PdePreprocessor.java +++ b/app/preproc/PdePreprocessor.java @@ -155,7 +155,8 @@ public class PdePreprocessor { PatternMatcher matcher = new Perl5Matcher(); PatternCompiler compiler = new Perl5Compiler(); //String mess = "^\\s*(import\\s+\\S+\\s*;)"; - String mess = "^\\s*(import\\s+)(\\S+)(\\s*;)"; + //String mess = "^\\s*(import\\s+)(\\S+)(\\s*;)"; + String mess = "^\\s*(#include\\s+[<\"])(\\S+)([\">]\\s*)"; java.util.Vector imports = new java.util.Vector(); Pattern pattern = null; @@ -166,14 +167,13 @@ public class PdePreprocessor { return null; } - /* do { PatternMatcherInput input = new PatternMatcherInput(program); if (!matcher.contains(input, pattern)) break; MatchResult result = matcher.getMatch(); String piece1 = result.group(1).toString(); - String piece2 = result.group(2).toString(); // the package name + String piece2 = result.group(2).toString(); // the header file name w/o quotes String piece3 = result.group(3).toString(); String piece = piece1 + piece2 + piece3; int len = piece.length(); @@ -187,7 +187,7 @@ public class PdePreprocessor { //System.out.println("removing " + piece); } while (true); - */ + extraImports = new String[imports.size()]; imports.copyInto(extraImports); @@ -380,9 +380,10 @@ public class PdePreprocessor { * @param exporting Is this being exported from PDE? * @param name Name of the class being created. */ - void writeHeader(PrintStream out, String className, java.util.LinkedList prototypes) { + void writeHeader(PrintStream out, String className, java.util.LinkedList prototypes) + throws IOException { out.print("#include \"WProgram.h\"\n"); - + /* Arduino doesn't automatically use all available libraries. // print library headers LibraryManager libraryManager = new LibraryManager(); String[] headerFiles = libraryManager.getHeaderFiles(); @@ -392,7 +393,7 @@ public class PdePreprocessor { // record number of header lines written for error line adjustment headerCount = headerFiles.length; - + */ // print user defined prototypes while(0 < prototypes.size()){ out.print(prototypes.removeFirst() + "\n"); diff --git a/build/macosx/Arduino.xcodeproj/project.pbxproj b/build/macosx/Arduino.xcodeproj/project.pbxproj index dd4247912..8346df93b 100644 --- a/build/macosx/Arduino.xcodeproj/project.pbxproj +++ b/build/macosx/Arduino.xcodeproj/project.pbxproj @@ -219,10 +219,10 @@ 33AF61B30965C54B00B514A9 /* WTreeParser.java in Sources */ = {isa = PBXBuildFile; fileRef = 33FFFE520965BD110016AC38 /* WTreeParser.java */; }; 33AF61B40965C54B00B514A9 /* JEditTextArea.java in Sources */ = {isa = PBXBuildFile; fileRef = 33FFFE630965BD110016AC38 /* JEditTextArea.java */; }; 33AF61B50965C54B00B514A9 /* Base.java in Sources */ = {isa = PBXBuildFile; fileRef = 33FFFE240965BD100016AC38 /* Base.java */; }; - 33BEDDB109D6DC1300430D5B /* Library.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDAF09D6DC1300430D5B /* Library.java */; }; 33BEDDB209D6DC1300430D5B /* LibraryManager.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDB009D6DC1300430D5B /* LibraryManager.java */; }; 33BEDDD509D6E8D800430D5B /* Archiver.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDD309D6E8D800430D5B /* Archiver.java */; }; 33BEDDD609D6E8D800430D5B /* ExportFolder.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEDDD409D6E8D800430D5B /* ExportFolder.java */; }; + 33BEE0CE09D7446100430D5B /* Library.java in Sources */ = {isa = PBXBuildFile; fileRef = 33BEE0CD09D7446100430D5B /* Library.java */; }; 33CF03B209662CB700F2C9A9 /* arduino.icns in Resources */ = {isa = PBXBuildFile; fileRef = 33CF03B009662CA800F2C9A9 /* arduino.icns */; }; 33CF03CC09662DC000F2C9A9 /* mrj.jar in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33AF620C0965D67900B514A9 /* mrj.jar */; settings = {JAVA_ARCHIVE_SUBDIR = ../shared/lib; }; }; 33CF03CD09662DC000F2C9A9 /* RXTXcomm.jar in CopyFiles */ = {isa = PBXBuildFile; fileRef = 33AF620F0965D67A00B514A9 /* RXTXcomm.jar */; settings = {JAVA_ARCHIVE_SUBDIR = ../shared/lib; }; }; @@ -375,10 +375,10 @@ 33AF620D0965D67900B514A9 /* oro.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = oro.jar; sourceTree = ""; }; 33AF620E0965D67A00B514A9 /* registry.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = registry.jar; sourceTree = ""; }; 33AF620F0965D67A00B514A9 /* RXTXcomm.jar */ = {isa = PBXFileReference; lastKnownFileType = archive.jar; path = RXTXcomm.jar; sourceTree = ""; }; - 33BEDDAF09D6DC1300430D5B /* Library.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = Library.java; sourceTree = ""; }; 33BEDDB009D6DC1300430D5B /* LibraryManager.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = LibraryManager.java; sourceTree = ""; }; 33BEDDD309D6E8D800430D5B /* Archiver.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = Archiver.java; sourceTree = ""; }; 33BEDDD409D6E8D800430D5B /* ExportFolder.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = ExportFolder.java; sourceTree = ""; }; + 33BEE0CD09D7446100430D5B /* Library.java */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.java; path = Library.java; sourceTree = ""; }; 33CF03B009662CA800F2C9A9 /* arduino.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = arduino.icns; path = dist/arduino.icns; sourceTree = ""; }; 33DD8FB6096AC8DA0013AF8F /* Arduino.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Arduino.app; sourceTree = BUILT_PRODUCTS_DIR; }; 33FF01DC0965BD160016AC38 /* examples.zip */ = {isa = PBXFileReference; lastKnownFileType = archive.zip; path = examples.zip; sourceTree = ""; }; @@ -746,7 +746,7 @@ 33FFFE220965BD100016AC38 /* app */ = { isa = PBXGroup; children = ( - 33BEDDAF09D6DC1300430D5B /* Library.java */, + 33BEE0CD09D7446100430D5B /* Library.java */, 33BEDDB009D6DC1300430D5B /* LibraryManager.java */, 33FFFE240965BD100016AC38 /* Base.java */, 33FFFE260965BD100016AC38 /* Compiler.java */, @@ -1138,10 +1138,10 @@ 33AF61B40965C54B00B514A9 /* JEditTextArea.java in Sources */, 33AF61B50965C54B00B514A9 /* Base.java in Sources */, 332D4DB609CF147F00BF81F6 /* Sizer.java in Sources */, - 33BEDDB109D6DC1300430D5B /* Library.java in Sources */, 33BEDDB209D6DC1300430D5B /* LibraryManager.java in Sources */, 33BEDDD509D6E8D800430D5B /* Archiver.java in Sources */, 33BEDDD609D6E8D800430D5B /* ExportFolder.java in Sources */, + 33BEE0CE09D7446100430D5B /* Library.java in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/targets/libraries/Foo/Foo.cpp b/targets/libraries/Foo/Foo.cpp new file mode 100644 index 000000000..00eee3742 --- /dev/null +++ b/targets/libraries/Foo/Foo.cpp @@ -0,0 +1,35 @@ +/* + Foo.cpp - test library + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "Foo.h" +#include "WProgram.h" + +Foo::Foo(int pin, int interval) +{ + this->pin = pin; + this->interval = interval; +} + +void Foo::foo() +{ + digitalWrite(pin, HIGH); + delay(interval); + digitalWrite(pin, LOW); + delay(interval); +} \ No newline at end of file diff --git a/targets/libraries/Foo/Foo.h b/targets/libraries/Foo/Foo.h new file mode 100644 index 000000000..68cae3fe1 --- /dev/null +++ b/targets/libraries/Foo/Foo.h @@ -0,0 +1,33 @@ +/* + Foo.h - test library + Copyright (c) 2006 David A. Mellis. All right reserved. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#ifndef Sprite_h +#define Sprite_h + +//#include + +class Foo { +private: + int pin, interval; +public: + Foo(int pin, int interval); + void foo(); +}; + +#endif \ No newline at end of file diff --git a/targets/libraries/Matrix.cpp b/targets/libraries/Matrix/Matrix.cpp similarity index 100% rename from targets/libraries/Matrix.cpp rename to targets/libraries/Matrix/Matrix.cpp diff --git a/targets/libraries/Matrix.h b/targets/libraries/Matrix/Matrix.h similarity index 100% rename from targets/libraries/Matrix.h rename to targets/libraries/Matrix/Matrix.h diff --git a/targets/libraries/Sprite.cpp b/targets/libraries/Sprite/Sprite.cpp similarity index 100% rename from targets/libraries/Sprite.cpp rename to targets/libraries/Sprite/Sprite.cpp diff --git a/targets/libraries/Sprite.h b/targets/libraries/Sprite/Sprite.h similarity index 100% rename from targets/libraries/Sprite.h rename to targets/libraries/Sprite/Sprite.h diff --git a/targets/arduino/binary.h b/targets/libraries/Sprite/binary.h similarity index 100% rename from targets/arduino/binary.h rename to targets/libraries/Sprite/binary.h