mirror of
https://github.com/arduino/Arduino.git
synced 2025-01-17 06:52:18 +01:00
Re-configured compilation and integrated uploading. Added the Board and Serial port menus: these are currently shared across editor windows.
No longer using Library and LibraryManager. Instead the compiler finds the .c and .cpp files in the library paths (gotten from the Sketch via the Preprocessor and the Base's library table). This breaks libraries that have header files in sub-directories but use #include with no path names (as sub-directories of library directories are not on the include path). It will also cause problems with .c or .cpp files with the same name in different library utility folders or in a sketch or the target (core). Now deriving the Target correctly from the selected item in the board menu.
This commit is contained in:
parent
ae98fbfee8
commit
14778514ae
BIN
app/lib/RXTXcomm.jar
Normal file
BIN
app/lib/RXTXcomm.jar
Normal file
Binary file not shown.
@ -286,7 +286,7 @@ public class Base {
|
||||
// Get paths for the libraries and examples in the Processing folder
|
||||
//String workingDirectory = System.getProperty("user.dir");
|
||||
examplesFolder = getContentFile("examples");
|
||||
librariesFolder = getContentFile("libraries");
|
||||
librariesFolder = new File(getContentFile("hardware"), "libraries");
|
||||
toolsFolder = getContentFile("tools");
|
||||
|
||||
// Get the sketchbook path, and make sure it's set properly
|
||||
@ -1109,11 +1109,11 @@ public class Base {
|
||||
|
||||
for (String libraryName : list) {
|
||||
File subfolder = new File(folder, libraryName);
|
||||
File libraryFolder = new File(subfolder, "library");
|
||||
File libraryJar = new File(libraryFolder, libraryName + ".jar");
|
||||
// If a .jar file of the same prefix as the folder exists
|
||||
// inside the 'library' subfolder of the sketch
|
||||
if (libraryJar.exists()) {
|
||||
// File libraryFolder = new File(subfolder, "library");
|
||||
// File libraryJar = new File(libraryFolder, libraryName + ".jar");
|
||||
// // If a .jar file of the same prefix as the folder exists
|
||||
// // inside the 'library' subfolder of the sketch
|
||||
// if (libraryJar.exists()) {
|
||||
String sanityCheck = Sketch.sanitizeName(libraryName);
|
||||
if (!sanityCheck.equals(libraryName)) {
|
||||
String mess =
|
||||
@ -1124,35 +1124,37 @@ public class Base {
|
||||
continue;
|
||||
}
|
||||
|
||||
// get the path for all .jar files in this code folder
|
||||
String libraryClassPath =
|
||||
Compiler.contentsToClassPath(libraryFolder);
|
||||
// grab all jars and classes from this folder,
|
||||
// and append them to the library classpath
|
||||
librariesClassPath +=
|
||||
File.pathSeparatorChar + libraryClassPath;
|
||||
// need to associate each import with a library folder
|
||||
String packages[] =
|
||||
Compiler.packageListFromClassPath(libraryClassPath);
|
||||
// // get the path for all .jar files in this code folder
|
||||
// String libraryClassPath =
|
||||
// Compiler.contentsToClassPath(libraryFolder);
|
||||
// // grab all jars and classes from this folder,
|
||||
// // and append them to the library classpath
|
||||
// librariesClassPath +=
|
||||
// File.pathSeparatorChar + libraryClassPath;
|
||||
// // need to associate each import with a library folder
|
||||
// String packages[] =
|
||||
// Compiler.packageListFromClassPath(libraryClassPath);
|
||||
String packages[] = Compiler.headerListFromIncludePath(subfolder.getAbsolutePath());
|
||||
for (String pkg : packages) {
|
||||
importToLibraryTable.put(pkg, libraryFolder);
|
||||
importToLibraryTable.put(pkg, subfolder);
|
||||
}
|
||||
|
||||
JMenuItem item = new JMenuItem(libraryName);
|
||||
item.addActionListener(listener);
|
||||
item.setActionCommand(libraryJar.getAbsolutePath());
|
||||
// item.setActionCommand(libraryJar.getAbsolutePath());
|
||||
menu.add(item);
|
||||
ifound = true;
|
||||
|
||||
} else { // not a library, but is still a folder, so recurse
|
||||
JMenu submenu = new JMenu(libraryName);
|
||||
// needs to be separate var, otherwise would set ifound to false
|
||||
boolean found = addLibraries(submenu, subfolder);
|
||||
if (found) {
|
||||
menu.add(submenu);
|
||||
ifound = true;
|
||||
}
|
||||
}
|
||||
// XXX: DAM: should recurse here so that library folders can be nested
|
||||
// } else { // not a library, but is still a folder, so recurse
|
||||
// JMenu submenu = new JMenu(libraryName);
|
||||
// // needs to be separate var, otherwise would set ifound to false
|
||||
// boolean found = addLibraries(submenu, subfolder);
|
||||
// if (found) {
|
||||
// menu.add(submenu);
|
||||
// ifound = true;
|
||||
// }
|
||||
// }
|
||||
}
|
||||
return ifound;
|
||||
}
|
||||
|
@ -42,6 +42,8 @@ import javax.swing.event.*;
|
||||
import javax.swing.text.*;
|
||||
import javax.swing.undo.*;
|
||||
|
||||
import gnu.io.*;
|
||||
|
||||
|
||||
/**
|
||||
* Main editor panel for the Processing Development Environment.
|
||||
@ -75,9 +77,12 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
PageFormat pageFormat;
|
||||
PrinterJob printerJob;
|
||||
|
||||
// file and sketch menus for re-inserting items
|
||||
// file, sketch, and tools menus for re-inserting items
|
||||
JMenu fileMenu;
|
||||
JMenu sketchMenu;
|
||||
JMenu toolsMenu;
|
||||
|
||||
int numTools = 0;
|
||||
|
||||
EditorToolbar toolbar;
|
||||
// these menus are shared so that they needn't be rebuilt for all windows
|
||||
@ -86,6 +91,14 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
static JMenu sketchbookMenu;
|
||||
static JMenu examplesMenu;
|
||||
static JMenu importMenu;
|
||||
|
||||
// these menus are shared so that the board and serial port selections
|
||||
// are the same for all windows (since the board and serial port that are
|
||||
// actually used are determined by the preferences, which are shared)
|
||||
static JMenu boardsMenu;
|
||||
static JMenu serialMenu;
|
||||
|
||||
static SerialMenuListener serialMenuListener;
|
||||
|
||||
EditorHeader header;
|
||||
EditorStatus status;
|
||||
@ -152,6 +165,8 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
fileMenu.insert(sketchbookMenu, 2);
|
||||
fileMenu.insert(examplesMenu, 3);
|
||||
sketchMenu.insert(importMenu, 4);
|
||||
toolsMenu.insert(boardsMenu, numTools);
|
||||
toolsMenu.insert(serialMenu, numTools + 1);
|
||||
}
|
||||
});
|
||||
|
||||
@ -595,13 +610,64 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
|
||||
protected JMenu buildToolsMenu() {
|
||||
JMenu menu = new JMenu("Tools");
|
||||
toolsMenu = new JMenu("Tools");
|
||||
JMenu menu = toolsMenu;
|
||||
JMenuItem item;
|
||||
|
||||
addInternalTools(menu);
|
||||
addTools(menu, Base.getToolsFolder());
|
||||
File sketchbookTools = new File(Base.getSketchbookFolder(), "tools");
|
||||
addTools(menu, sketchbookTools);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
numTools = menu.getItemCount();
|
||||
|
||||
// XXX: DAM: these should probably be implemented using the Tools plugin
|
||||
// API, if possible (i.e. if it supports custom actions, etc.)
|
||||
|
||||
if (boardsMenu == null) {
|
||||
boardsMenu = new JMenu("Board");
|
||||
ButtonGroup boardGroup = new ButtonGroup();
|
||||
for (Iterator i = Preferences.getSubKeys("boards"); i.hasNext(); ) {
|
||||
String board = (String) i.next();
|
||||
Action action = new BoardMenuAction(board);
|
||||
item = new JRadioButtonMenuItem(action);
|
||||
if (board.equals(Preferences.get("board")))
|
||||
item.setSelected(true);
|
||||
boardGroup.add(item);
|
||||
boardsMenu.add(item);
|
||||
}
|
||||
}
|
||||
menu.add(boardsMenu);
|
||||
|
||||
if (serialMenuListener == null)
|
||||
serialMenuListener = new SerialMenuListener();
|
||||
if (serialMenu == null)
|
||||
serialMenu = new JMenu("Serial Port");
|
||||
populateSerialMenu();
|
||||
menu.add(serialMenu);
|
||||
|
||||
menu.addSeparator();
|
||||
|
||||
JMenu bootloaderMenu = new JMenu("Burn Bootloader");
|
||||
for (Iterator i = Preferences.getSubKeys("programmers"); i.hasNext(); ) {
|
||||
String programmer = (String) i.next();
|
||||
Action action = new BootloaderMenuAction(programmer);
|
||||
item = new JMenuItem(action);
|
||||
bootloaderMenu.add(item);
|
||||
}
|
||||
menu.add(bootloaderMenu);
|
||||
|
||||
menu.addMenuListener(new MenuListener() {
|
||||
public void menuCanceled(MenuEvent e) {}
|
||||
public void menuDeselected(MenuEvent e) {}
|
||||
public void menuSelected(MenuEvent e) {
|
||||
//System.out.println("Tools menu selected.");
|
||||
populateSerialMenu();
|
||||
}
|
||||
});
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
@ -777,6 +843,113 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
}
|
||||
|
||||
|
||||
class SerialMenuListener implements ActionListener {
|
||||
//public SerialMenuListener() { }
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if(serialMenu == null) {
|
||||
System.out.println("serialMenu is null");
|
||||
return;
|
||||
}
|
||||
int count = serialMenu.getItemCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
((JCheckBoxMenuItem)serialMenu.getItem(i)).setState(false);
|
||||
}
|
||||
JCheckBoxMenuItem item = (JCheckBoxMenuItem)e.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getText();
|
||||
//System.out.println(item.getLabel());
|
||||
Preferences.set("serial.port", name);
|
||||
//System.out.println("set to " + get("serial.port"));
|
||||
}
|
||||
|
||||
/*
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
System.out.println(e.getSource());
|
||||
String name = e.getActionCommand();
|
||||
PdeBase.properties.put("serial.port", name);
|
||||
System.out.println("set to " + get("serial.port"));
|
||||
//editor.skOpen(path + File.separator + name, name);
|
||||
// need to push "serial.port" into PdeBase.properties
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
class BoardMenuAction extends AbstractAction {
|
||||
private String board;
|
||||
public BoardMenuAction(String board) {
|
||||
super(Preferences.get("boards." + board + ".name"));
|
||||
this.board = board;
|
||||
}
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
//System.out.println("Switching to " + board);
|
||||
Preferences.set("board", board);
|
||||
}
|
||||
}
|
||||
|
||||
class BootloaderMenuAction extends AbstractAction {
|
||||
private String programmer;
|
||||
public BootloaderMenuAction(String programmer) {
|
||||
super("w/ " + Preferences.get("programmers." + programmer + ".name"));
|
||||
this.programmer = programmer;
|
||||
}
|
||||
public void actionPerformed(ActionEvent actionevent) {
|
||||
// XXX: DAM: need to actually burn the bootloader here.
|
||||
// handleBurnBootloader(programmer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
protected void populateSerialMenu() {
|
||||
// getting list of ports
|
||||
|
||||
JMenuItem rbMenuItem;
|
||||
|
||||
//System.out.println("Clearing serial port menu.");
|
||||
|
||||
serialMenu.removeAll();
|
||||
boolean empty = true;
|
||||
|
||||
try
|
||||
{
|
||||
for (Enumeration enumeration = CommPortIdentifier.getPortIdentifiers(); enumeration.hasMoreElements();)
|
||||
{
|
||||
CommPortIdentifier commportidentifier = (CommPortIdentifier)enumeration.nextElement();
|
||||
//System.out.println("Found communication port: " + commportidentifier);
|
||||
if (commportidentifier.getPortType() == CommPortIdentifier.PORT_SERIAL)
|
||||
{
|
||||
//System.out.println("Adding port to serial port menu: " + commportidentifier);
|
||||
String curr_port = commportidentifier.getName();
|
||||
rbMenuItem = new JCheckBoxMenuItem(curr_port, curr_port.equals(Preferences.get("serial.port")));
|
||||
rbMenuItem.addActionListener(serialMenuListener);
|
||||
//serialGroup.add(rbMenuItem);
|
||||
serialMenu.add(rbMenuItem);
|
||||
empty = false;
|
||||
}
|
||||
}
|
||||
if (!empty) {
|
||||
//System.out.println("enabling the serialMenu");
|
||||
serialMenu.setEnabled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
catch (Exception exception)
|
||||
{
|
||||
System.out.println("error retrieving port list");
|
||||
exception.printStackTrace();
|
||||
}
|
||||
|
||||
if (serialMenu.getItemCount() == 0) {
|
||||
serialMenu.setEnabled(false);
|
||||
}
|
||||
|
||||
//serialMenu.addSeparator();
|
||||
//serialMenu.add(item);
|
||||
}
|
||||
|
||||
|
||||
protected JMenu buildHelpMenu() {
|
||||
JMenu menu = new JMenu("Help");
|
||||
JMenuItem item;
|
||||
@ -1548,7 +1721,7 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
internalCloseRunner();
|
||||
running = true;
|
||||
toolbar.activate(EditorToolbar.RUN);
|
||||
statusEmpty();
|
||||
statusNotice("Compiling...");
|
||||
|
||||
// do this to advance/clear the terminal window / dos prompt / etc
|
||||
for (int i = 0; i < 10; i++) System.out.println();
|
||||
@ -1560,30 +1733,24 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
|
||||
presenting = present;
|
||||
|
||||
try {
|
||||
// XXX: DAM: don't hardcode this to "arduino"
|
||||
String appletClassName = sketch.compile(
|
||||
new Target(Base.getHardwarePath() + File.separator + "cores",
|
||||
"arduino"));
|
||||
if (appletClassName != null) {
|
||||
runtime = new Runner(sketch, appletClassName, presenting, Editor.this);
|
||||
SwingUtilities.invokeLater(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
sketch.compile(new Target(
|
||||
Base.getHardwarePath() + File.separator + "cores",
|
||||
Preferences.get("boards." + Preferences.get("board") + ".build.core")));
|
||||
statusNotice("Done compiling.");
|
||||
} catch (RunnerException e) {
|
||||
//statusError("Error compiling...");
|
||||
statusError(e);
|
||||
|
||||
// Cannot use invokeLater() here, otherwise it gets
|
||||
// placed on the event thread and causes a hang--bad idea all around.
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
runtime.launch();
|
||||
}
|
||||
});
|
||||
t.start();
|
||||
//runtime.start(appletLocation);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
toolbar.deactivate(EditorToolbar.RUN);
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
//System.err.println("exception reached editor");
|
||||
//e.printStackTrace();
|
||||
statusError(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -1960,24 +2127,38 @@ public class Editor extends JFrame implements RunnerListener {
|
||||
* Made synchronized to (hopefully) avoid problems of people
|
||||
* hitting export twice, quickly, and horking things up.
|
||||
*/
|
||||
/**
|
||||
* Handles calling the export() function on sketch, and
|
||||
* queues all the gui status stuff that comes along with it.
|
||||
*
|
||||
* Made synchronized to (hopefully) avoid problems of people
|
||||
* hitting export twice, quickly, and horking things up.
|
||||
*/
|
||||
synchronized public void handleExport() {
|
||||
if (!handleExportCheckModified()) return;
|
||||
toolbar.activate(EditorToolbar.EXPORT);
|
||||
|
||||
console.clear();
|
||||
statusNotice("Uploading to I/O Board...");
|
||||
|
||||
//SwingUtilities.invokeLater(new Runnable() {
|
||||
Thread t = new Thread(new Runnable() {
|
||||
public void run() {
|
||||
try {
|
||||
boolean success = sketch.exportApplet();
|
||||
boolean success = sketch.exportApplet(new Target(
|
||||
Base.getHardwarePath() + File.separator + "cores",
|
||||
Preferences.get("boards." + Preferences.get("board") + ".build.core")));
|
||||
if (success) {
|
||||
File appletFolder = new File(sketch.getFolder(), "applet");
|
||||
Base.openFolder(appletFolder);
|
||||
statusNotice("Done exporting.");
|
||||
statusNotice("Done uploading.");
|
||||
} else {
|
||||
// error message will already be visible
|
||||
}
|
||||
} catch (Exception e) {
|
||||
} catch (RunnerException e) {
|
||||
//statusError("Error during upload.");
|
||||
//e.printStackTrace();
|
||||
statusError(e);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
//toolbar.clear();
|
||||
toolbar.deactivate(EditorToolbar.EXPORT);
|
||||
|
617
app/src/processing/app/Serial.java
Executable file
617
app/src/processing/app/Serial.java
Executable file
@ -0,0 +1,617 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
PSerial - class for serial port goodness
|
||||
Part of the Processing project - http://processing.org
|
||||
|
||||
Copyright (c) 2004 Ben Fry & Casey Reas
|
||||
|
||||
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., 59 Temple Place, Suite 330,
|
||||
Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
//import processing.core.*;
|
||||
|
||||
import gnu.io.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
|
||||
public class Serial implements SerialPortEventListener {
|
||||
|
||||
//PApplet parent;
|
||||
|
||||
// properties can be passed in for default values
|
||||
// otherwise defaults to 9600 N81
|
||||
|
||||
// these could be made static, which might be a solution
|
||||
// for the classloading problem.. because if code ran again,
|
||||
// the static class would have an object that could be closed
|
||||
|
||||
SerialPort port;
|
||||
|
||||
int rate;
|
||||
int parity;
|
||||
int databits;
|
||||
int stopbits;
|
||||
boolean monitor = false;
|
||||
|
||||
// read buffer and streams
|
||||
|
||||
InputStream input;
|
||||
OutputStream output;
|
||||
|
||||
byte buffer[] = new byte[32768];
|
||||
int bufferIndex;
|
||||
int bufferLast;
|
||||
|
||||
public Serial(boolean monitor) throws SerialException {
|
||||
this(Preferences.get("serial.port"),
|
||||
Preferences.getInteger("serial.debug_rate"),
|
||||
Preferences.get("serial.parity").charAt(0),
|
||||
Preferences.getInteger("serial.databits"),
|
||||
new Float(Preferences.get("serial.stopbits")).floatValue());
|
||||
this.monitor = monitor;
|
||||
}
|
||||
|
||||
public Serial() throws SerialException {
|
||||
this(Preferences.get("serial.port"),
|
||||
Preferences.getInteger("serial.debug_rate"),
|
||||
Preferences.get("serial.parity").charAt(0),
|
||||
Preferences.getInteger("serial.databits"),
|
||||
new Float(Preferences.get("serial.stopbits")).floatValue());
|
||||
}
|
||||
|
||||
public Serial(int irate) throws SerialException {
|
||||
this(Preferences.get("serial.port"), irate,
|
||||
Preferences.get("serial.parity").charAt(0),
|
||||
Preferences.getInteger("serial.databits"),
|
||||
new Float(Preferences.get("serial.stopbits")).floatValue());
|
||||
}
|
||||
|
||||
public Serial(String iname, int irate) throws SerialException {
|
||||
this(iname, irate, Preferences.get("serial.parity").charAt(0),
|
||||
Preferences.getInteger("serial.databits"),
|
||||
new Float(Preferences.get("serial.stopbits")).floatValue());
|
||||
}
|
||||
|
||||
public Serial(String iname) throws SerialException {
|
||||
this(iname, Preferences.getInteger("serial.debug_rate"),
|
||||
Preferences.get("serial.parity").charAt(0),
|
||||
Preferences.getInteger("serial.databits"),
|
||||
new Float(Preferences.get("serial.stopbits")).floatValue());
|
||||
}
|
||||
|
||||
public Serial(String iname, int irate,
|
||||
char iparity, int idatabits, float istopbits)
|
||||
throws SerialException {
|
||||
//if (port != null) port.close();
|
||||
//this.parent = parent;
|
||||
//parent.attach(this);
|
||||
|
||||
this.rate = irate;
|
||||
|
||||
parity = SerialPort.PARITY_NONE;
|
||||
if (iparity == 'E') parity = SerialPort.PARITY_EVEN;
|
||||
if (iparity == 'O') parity = SerialPort.PARITY_ODD;
|
||||
|
||||
this.databits = idatabits;
|
||||
|
||||
stopbits = SerialPort.STOPBITS_1;
|
||||
if (istopbits == 1.5f) stopbits = SerialPort.STOPBITS_1_5;
|
||||
if (istopbits == 2) stopbits = SerialPort.STOPBITS_2;
|
||||
|
||||
try {
|
||||
port = null;
|
||||
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
|
||||
while (portList.hasMoreElements()) {
|
||||
CommPortIdentifier portId =
|
||||
(CommPortIdentifier) portList.nextElement();
|
||||
|
||||
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
|
||||
//System.out.println("found " + portId.getName());
|
||||
if (portId.getName().equals(iname)) {
|
||||
//System.out.println("looking for "+iname);
|
||||
port = (SerialPort)portId.open("serial madness", 2000);
|
||||
input = port.getInputStream();
|
||||
output = port.getOutputStream();
|
||||
port.setSerialPortParams(rate, databits, stopbits, parity);
|
||||
port.addEventListener(this);
|
||||
port.notifyOnDataAvailable(true);
|
||||
//System.out.println("opening, ready to roll");
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (PortInUseException e) {
|
||||
throw new SerialException("Serial port '" + iname + "' already in use. Try quiting any programs that may be using it.");
|
||||
} catch (Exception e) {
|
||||
throw new SerialException("Error opening serial port '" + iname + "'.", e);
|
||||
// //errorMessage("<init>", e);
|
||||
// //exception = e;
|
||||
// //e.printStackTrace();
|
||||
}
|
||||
|
||||
if (port == null) {
|
||||
throw new SerialException("Serial port '" + iname + "' not found. Did you select the right one from the Tools > Serial Port menu?");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void setup() {
|
||||
//parent.registerCall(this, DISPOSE);
|
||||
}
|
||||
|
||||
|
||||
//public void size(int w, int h) { }
|
||||
|
||||
//public void pre() { }
|
||||
|
||||
//public void draw() { }
|
||||
|
||||
//public void post() { }
|
||||
|
||||
//public void mouse(java.awt.event.MouseEvent event) { }
|
||||
|
||||
//public void key(java.awt.event.KeyEvent e) { }
|
||||
|
||||
|
||||
public void dispose() {
|
||||
try {
|
||||
// do io streams need to be closed first?
|
||||
if (input != null) input.close();
|
||||
if (output != null) output.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
input = null;
|
||||
output = null;
|
||||
|
||||
try {
|
||||
if (port != null) port.close(); // close the port
|
||||
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
port = null;
|
||||
}
|
||||
|
||||
|
||||
synchronized public void serialEvent(SerialPortEvent serialEvent) {
|
||||
//System.out.println("serial port event"); // " + serialEvent);
|
||||
//System.out.flush();
|
||||
//System.out.println("into");
|
||||
//System.out.flush();
|
||||
//System.err.println("type " + serialEvent.getEventType());
|
||||
//System.err.println("ahoooyey");
|
||||
//System.err.println("ahoooyeysdfsdfsdf");
|
||||
if (serialEvent.getEventType() == SerialPortEvent.DATA_AVAILABLE) {
|
||||
//System.out.println("data available");
|
||||
//System.err.flush();
|
||||
try {
|
||||
while (input.available() > 0) {
|
||||
//if (input.available() > 0) {
|
||||
//serial = input.read();
|
||||
//serialEvent();
|
||||
//buffer[bufferCount++] = (byte) serial;
|
||||
synchronized (buffer) {
|
||||
if (bufferLast == buffer.length) {
|
||||
byte temp[] = new byte[bufferLast << 1];
|
||||
System.arraycopy(buffer, 0, temp, 0, bufferLast);
|
||||
buffer = temp;
|
||||
}
|
||||
//buffer[bufferLast++] = (byte) input.read();
|
||||
if(monitor == true)
|
||||
System.out.print((char) input.read());
|
||||
|
||||
/*
|
||||
System.err.println(input.available() + " " +
|
||||
((char) buffer[bufferLast-1]));
|
||||
*/ //}
|
||||
}
|
||||
}
|
||||
//System.out.println("no more");
|
||||
|
||||
} catch (IOException e) {
|
||||
errorMessage("serialEvent", e);
|
||||
//e.printStackTrace();
|
||||
//System.out.println("angry");
|
||||
}
|
||||
catch (Exception e) {
|
||||
}
|
||||
}
|
||||
//System.out.println("out of");
|
||||
//System.err.println("out of event " + serialEvent.getEventType());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the number of bytes that have been read from serial
|
||||
* and are waiting to be dealt with by the user.
|
||||
*/
|
||||
public int available() {
|
||||
return (bufferLast - bufferIndex);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ignore all the bytes read so far and empty the buffer.
|
||||
*/
|
||||
public void clear() {
|
||||
bufferLast = 0;
|
||||
bufferIndex = 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns a number between 0 and 255 for the next byte that's
|
||||
* waiting in the buffer.
|
||||
* Returns -1 if there was no byte (although the user should
|
||||
* first check available() to see if things are ready to avoid this)
|
||||
*/
|
||||
public int read() {
|
||||
if (bufferIndex == bufferLast) return -1;
|
||||
|
||||
synchronized (buffer) {
|
||||
int outgoing = buffer[bufferIndex++] & 0xff;
|
||||
if (bufferIndex == bufferLast) { // rewind
|
||||
bufferIndex = 0;
|
||||
bufferLast = 0;
|
||||
}
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the next byte in the buffer as a char.
|
||||
* Returns -1, or 0xffff, if nothing is there.
|
||||
*/
|
||||
public char readChar() {
|
||||
if (bufferIndex == bufferLast) return (char)(-1);
|
||||
return (char) read();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return a byte array of anything that's in the serial buffer.
|
||||
* Not particularly memory/speed efficient, because it creates
|
||||
* a byte array on each read, but it's easier to use than
|
||||
* readBytes(byte b[]) (see below).
|
||||
*/
|
||||
public byte[] readBytes() {
|
||||
if (bufferIndex == bufferLast) return null;
|
||||
|
||||
synchronized (buffer) {
|
||||
int length = bufferLast - bufferIndex;
|
||||
byte outgoing[] = new byte[length];
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Grab whatever is in the serial buffer, and stuff it into a
|
||||
* byte buffer passed in by the user. This is more memory/time
|
||||
* efficient than readBytes() returning a byte[] array.
|
||||
*
|
||||
* Returns an int for how many bytes were read. If more bytes
|
||||
* are available than can fit into the byte array, only those
|
||||
* that will fit are read.
|
||||
*/
|
||||
public int readBytes(byte outgoing[]) {
|
||||
if (bufferIndex == bufferLast) return 0;
|
||||
|
||||
synchronized (buffer) {
|
||||
int length = bufferLast - bufferIndex;
|
||||
if (length > outgoing.length) length = outgoing.length;
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex += length;
|
||||
if (bufferIndex == bufferLast) {
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads from the serial port into a buffer of bytes up to and
|
||||
* including a particular character. If the character isn't in
|
||||
* the serial buffer, then 'null' is returned.
|
||||
*/
|
||||
public byte[] readBytesUntil(int interesting) {
|
||||
if (bufferIndex == bufferLast) return null;
|
||||
byte what = (byte)interesting;
|
||||
|
||||
synchronized (buffer) {
|
||||
int found = -1;
|
||||
for (int k = bufferIndex; k < bufferLast; k++) {
|
||||
if (buffer[k] == what) {
|
||||
found = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == -1) return null;
|
||||
|
||||
int length = found - bufferIndex + 1;
|
||||
byte outgoing[] = new byte[length];
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
return outgoing;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Reads from the serial port into a buffer of bytes until a
|
||||
* particular character. If the character isn't in the serial
|
||||
* buffer, then 'null' is returned.
|
||||
*
|
||||
* If outgoing[] is not big enough, then -1 is returned,
|
||||
* and an error message is printed on the console.
|
||||
* If nothing is in the buffer, zero is returned.
|
||||
* If 'interesting' byte is not in the buffer, then 0 is returned.
|
||||
*/
|
||||
public int readBytesUntil(int interesting, byte outgoing[]) {
|
||||
if (bufferIndex == bufferLast) return 0;
|
||||
byte what = (byte)interesting;
|
||||
|
||||
synchronized (buffer) {
|
||||
int found = -1;
|
||||
for (int k = bufferIndex; k < bufferLast; k++) {
|
||||
if (buffer[k] == what) {
|
||||
found = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (found == -1) return 0;
|
||||
|
||||
int length = found - bufferIndex + 1;
|
||||
if (length > outgoing.length) {
|
||||
System.err.println("readBytesUntil() byte buffer is" +
|
||||
" too small for the " + length +
|
||||
" bytes up to and including char " + interesting);
|
||||
return -1;
|
||||
}
|
||||
//byte outgoing[] = new byte[length];
|
||||
System.arraycopy(buffer, bufferIndex, outgoing, 0, length);
|
||||
|
||||
bufferIndex += length;
|
||||
if (bufferIndex == bufferLast) {
|
||||
bufferIndex = 0; // rewind
|
||||
bufferLast = 0;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return whatever has been read from the serial port so far
|
||||
* as a String. It assumes that the incoming characters are ASCII.
|
||||
*
|
||||
* If you want to move Unicode data, you can first convert the
|
||||
* String to a byte stream in the representation of your choice
|
||||
* (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
|
||||
*/
|
||||
public String readString() {
|
||||
if (bufferIndex == bufferLast) return null;
|
||||
return new String(readBytes());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Combination of readBytesUntil and readString. See caveats in
|
||||
* each function. Returns null if it still hasn't found what
|
||||
* you're looking for.
|
||||
*
|
||||
* If you want to move Unicode data, you can first convert the
|
||||
* String to a byte stream in the representation of your choice
|
||||
* (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
|
||||
*/
|
||||
public String readStringUntil(int interesting) {
|
||||
byte b[] = readBytesUntil(interesting);
|
||||
if (b == null) return null;
|
||||
return new String(b);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This will handle both ints, bytes and chars transparently.
|
||||
*/
|
||||
public void write(int what) { // will also cover char
|
||||
try {
|
||||
output.write(what & 0xff); // for good measure do the &
|
||||
output.flush(); // hmm, not sure if a good idea
|
||||
|
||||
} catch (Exception e) { // null pointer or serial port dead
|
||||
errorMessage("write", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void write(byte bytes[]) {
|
||||
try {
|
||||
output.write(bytes);
|
||||
output.flush(); // hmm, not sure if a good idea
|
||||
|
||||
} catch (Exception e) { // null pointer or serial port dead
|
||||
//errorMessage("write", e);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Write a String to the output. Note that this doesn't account
|
||||
* for Unicode (two bytes per char), nor will it send UTF8
|
||||
* characters.. It assumes that you mean to send a byte buffer
|
||||
* (most often the case for networking and serial i/o) and
|
||||
* will only use the bottom 8 bits of each char in the string.
|
||||
* (Meaning that internally it uses String.getBytes)
|
||||
*
|
||||
* If you want to move Unicode data, you can first convert the
|
||||
* String to a byte stream in the representation of your choice
|
||||
* (i.e. UTF8 or two-byte Unicode data), and send it as a byte array.
|
||||
*/
|
||||
public void write(String what) {
|
||||
write(what.getBytes());
|
||||
}
|
||||
|
||||
public void setDTR(boolean state) {
|
||||
port.setDTR(state);
|
||||
}
|
||||
|
||||
/**
|
||||
* If this just hangs and never completes on Windows,
|
||||
* it may be because the DLL doesn't have its exec bit set.
|
||||
* Why the hell that'd be the case, who knows.
|
||||
*/
|
||||
static public String[] list() {
|
||||
Vector list = new Vector();
|
||||
try {
|
||||
//System.err.println("trying");
|
||||
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
|
||||
//System.err.println("got port list");
|
||||
while (portList.hasMoreElements()) {
|
||||
CommPortIdentifier portId =
|
||||
(CommPortIdentifier) portList.nextElement();
|
||||
//System.out.println(portId);
|
||||
|
||||
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
|
||||
String name = portId.getName();
|
||||
list.addElement(name);
|
||||
}
|
||||
}
|
||||
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
//System.err.println("1");
|
||||
errorMessage("ports", e);
|
||||
|
||||
} catch (Exception e) {
|
||||
//System.err.println("2");
|
||||
errorMessage("ports", e);
|
||||
}
|
||||
//System.err.println("move out");
|
||||
String outgoing[] = new String[list.size()];
|
||||
list.copyInto(outgoing);
|
||||
return outgoing;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* General error reporting, all corraled here just in case
|
||||
* I think of something slightly more intelligent to do.
|
||||
*/
|
||||
static public void errorMessage(String where, Throwable e) {
|
||||
System.err.println("Error inside Serial." + where + "()");
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
class SerialMenuListener implements ItemListener {
|
||||
//public SerialMenuListener() { }
|
||||
|
||||
public void itemStateChanged(ItemEvent e) {
|
||||
int count = serialMenu.getItemCount();
|
||||
for (int i = 0; i < count; i++) {
|
||||
((CheckboxMenuItem)serialMenu.getItem(i)).setState(false);
|
||||
}
|
||||
CheckboxMenuItem item = (CheckboxMenuItem)e.getSource();
|
||||
item.setState(true);
|
||||
String name = item.getLabel();
|
||||
//System.out.println(item.getLabel());
|
||||
PdeBase.properties.put("serial.port", name);
|
||||
//System.out.println("set to " + get("serial.port"));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
/*
|
||||
protected Vector buildPortList() {
|
||||
// get list of names for serial ports
|
||||
// have the default port checked (if present)
|
||||
Vector list = new Vector();
|
||||
|
||||
//SerialMenuListener listener = new SerialMenuListener();
|
||||
boolean problem = false;
|
||||
|
||||
// if this is failing, it may be because
|
||||
// lib/javax.comm.properties is missing.
|
||||
// java is weird about how it searches for java.comm.properties
|
||||
// so it tends to be very fragile. i.e. quotes in the CLASSPATH
|
||||
// environment variable will hose things.
|
||||
try {
|
||||
//System.out.println("building port list");
|
||||
Enumeration portList = CommPortIdentifier.getPortIdentifiers();
|
||||
while (portList.hasMoreElements()) {
|
||||
CommPortIdentifier portId =
|
||||
(CommPortIdentifier) portList.nextElement();
|
||||
//System.out.println(portId);
|
||||
|
||||
if (portId.getPortType() == CommPortIdentifier.PORT_SERIAL) {
|
||||
//if (portId.getName().equals(port)) {
|
||||
String name = portId.getName();
|
||||
//CheckboxMenuItem mi =
|
||||
//new CheckboxMenuItem(name, name.equals(defaultName));
|
||||
|
||||
//mi.addItemListener(listener);
|
||||
//serialMenu.add(mi);
|
||||
list.addElement(name);
|
||||
}
|
||||
}
|
||||
} catch (UnsatisfiedLinkError e) {
|
||||
e.printStackTrace();
|
||||
problem = true;
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("exception building serial menu");
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
//if (serialMenu.getItemCount() == 0) {
|
||||
//System.out.println("dimming serial menu");
|
||||
//serialMenu.setEnabled(false);
|
||||
//}
|
||||
|
||||
// only warn them if this is the first time
|
||||
if (problem && PdeBase.firstTime) {
|
||||
JOptionPane.showMessageDialog(this, //frame,
|
||||
"Serial port support not installed.\n" +
|
||||
"Check the readme for instructions\n" +
|
||||
"if you need to use the serial port. ",
|
||||
"Serial Port Warning",
|
||||
JOptionPane.WARNING_MESSAGE);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
39
app/src/processing/app/SerialException.java
Normal file
39
app/src/processing/app/SerialException.java
Normal file
@ -0,0 +1,39 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Copyright (c) 2007 David A. Mellis
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
|
||||
public class SerialException extends Exception {
|
||||
public SerialException() {
|
||||
super();
|
||||
}
|
||||
|
||||
public SerialException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public SerialException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public SerialException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
}
|
@ -23,11 +23,11 @@
|
||||
|
||||
package processing.app;
|
||||
|
||||
import processing.app.debug.AvrdudeUploader;
|
||||
import processing.app.debug.Compiler;
|
||||
import processing.app.debug.Library;
|
||||
import processing.app.debug.LibraryManager;
|
||||
import processing.app.debug.RunnerException;
|
||||
import processing.app.debug.Target;
|
||||
import processing.app.debug.Uploader;
|
||||
import processing.app.preproc.*;
|
||||
import processing.core.*;
|
||||
|
||||
@ -95,7 +95,7 @@ public class Sketch {
|
||||
* DLLs or JNILIBs.
|
||||
*/
|
||||
private String libraryPath;
|
||||
public Vector importedLibraries;
|
||||
private ArrayList<File> importedLibraries;
|
||||
|
||||
/**
|
||||
* path is location of the main .pde file, because this is also
|
||||
@ -1310,31 +1310,18 @@ public class Sketch {
|
||||
|
||||
// grab the imports from the code just preproc'd
|
||||
|
||||
importedLibraries = new Vector();
|
||||
ArrayList<String> imports = preprocessor.getExtraImports();
|
||||
try {
|
||||
LibraryManager libraryManager = new LibraryManager();
|
||||
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.size(); k++)
|
||||
if (headerFiles[j].getName().equals(imports.get(k)) &&
|
||||
!importedLibraries.contains(library)) {
|
||||
importedLibraries.add(library);
|
||||
//System.out.println("Adding library " + library.getName());
|
||||
}
|
||||
importedLibraries = new ArrayList<File>();
|
||||
|
||||
for (String item : preprocessor.getExtraImports()) {
|
||||
File libFolder = (File) Base.importToLibraryTable.get(item);
|
||||
|
||||
if (libFolder != null) {
|
||||
importedLibraries.add(libFolder);
|
||||
classPath += Compiler.contentsToClassPath(libFolder);
|
||||
libraryPath += File.pathSeparator + libFolder.getAbsolutePath();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
System.err.println("Error finding libraries:");
|
||||
e.printStackTrace();
|
||||
throw new RunnerException(e.getMessage());
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 3. then loop over the code[] and save each .java file
|
||||
|
||||
for (SketchCode sc : code) {
|
||||
@ -1385,16 +1372,66 @@ public class Sketch {
|
||||
}
|
||||
|
||||
|
||||
protected boolean exportApplet() throws Exception {
|
||||
return exportApplet(new File(folder, "applet").getAbsolutePath());
|
||||
protected boolean exportApplet(Target target) throws Exception {
|
||||
return exportApplet(new File(folder, "applet").getAbsolutePath(), target);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Handle export to applet.
|
||||
*/
|
||||
public boolean exportApplet(String appletPath) throws RunnerException, IOException {
|
||||
return false;
|
||||
public boolean exportApplet(String appletPath, Target target)
|
||||
throws RunnerException, IOException {
|
||||
|
||||
// Make sure the user didn't hide the sketch folder
|
||||
ensureExistence();
|
||||
|
||||
// Reload the code when an external editor is being used
|
||||
if (Preferences.getBoolean("editor.external")) {
|
||||
// nuke previous files and settings
|
||||
load();
|
||||
}
|
||||
|
||||
File appletFolder = new File(appletPath);
|
||||
// Nuke the old applet folder because it can cause trouble
|
||||
if (Preferences.getBoolean("export.delete_target_folder")) {
|
||||
Base.removeDir(appletFolder);
|
||||
}
|
||||
// Create a fresh applet folder (needed before preproc is run below)
|
||||
appletFolder.mkdirs();
|
||||
|
||||
// build the sketch
|
||||
String foundName = build(appletFolder.getPath(), target);
|
||||
// (already reported) error during export, exit this function
|
||||
if (foundName == null) return false;
|
||||
|
||||
// // If name != exportSketchName, then that's weirdness
|
||||
// // BUG unfortunately, that can also be a bug in the preproc :(
|
||||
// if (!name.equals(foundName)) {
|
||||
// Base.showWarning("Error during export",
|
||||
// "Sketch name is " + name + " but the sketch\n" +
|
||||
// "name in the code was " + foundName, null);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//size(appletFolder.getPath(), name);
|
||||
upload(appletFolder.getPath(), foundName);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected String upload(String buildPath, String suggestedClassName)
|
||||
throws RunnerException {
|
||||
|
||||
Uploader uploader;
|
||||
|
||||
// download the program
|
||||
//
|
||||
uploader = new AvrdudeUploader();
|
||||
boolean success = uploader.uploadUsingPreferences(buildPath,
|
||||
suggestedClassName);
|
||||
|
||||
return success ? suggestedClassName : null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1815,6 +1852,11 @@ public class Sketch {
|
||||
}
|
||||
return codeFolder;
|
||||
}
|
||||
|
||||
|
||||
public ArrayList<File> getImportedLibraries() {
|
||||
return importedLibraries;
|
||||
}
|
||||
|
||||
|
||||
public String getClassPath() {
|
||||
|
173
app/src/processing/app/debug/AvrdudeUploader.java
Executable file
173
app/src/processing/app/debug/AvrdudeUploader.java
Executable file
@ -0,0 +1,173 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
AvrdudeUploader - uploader implementation using avrdude
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2004-05
|
||||
Hernando Barragan
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
package processing.app.debug;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.Serial;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import javax.swing.*;
|
||||
import gnu.io.*;
|
||||
|
||||
|
||||
public class AvrdudeUploader extends Uploader {
|
||||
public AvrdudeUploader() {
|
||||
}
|
||||
|
||||
// XXX: add support for uploading sketches using a programmer
|
||||
public boolean uploadUsingPreferences(String buildPath, String className)
|
||||
throws RunnerException {
|
||||
String uploadUsing = Preferences.get("boards." + Preferences.get("board") + ".upload.using");
|
||||
if (uploadUsing == null) {
|
||||
// fall back on global preference
|
||||
uploadUsing = Preferences.get("upload.using");
|
||||
}
|
||||
if (uploadUsing.equals("bootloader")) {
|
||||
return uploadViaBootloader(buildPath, className);
|
||||
} else {
|
||||
Collection params = getProgrammerCommands(uploadUsing);
|
||||
params.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
|
||||
return avrdude(params);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean uploadViaBootloader(String buildPath, String className)
|
||||
throws RunnerException {
|
||||
List commandDownloader = new ArrayList();
|
||||
String protocol = Preferences.get("boards." + Preferences.get("board") + ".upload.protocol");
|
||||
|
||||
// avrdude wants "stk500v1" to distinguish it from stk500v2
|
||||
if (protocol.equals("stk500"))
|
||||
protocol = "stk500v1";
|
||||
commandDownloader.add("-c" + protocol);
|
||||
commandDownloader.add("-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
|
||||
commandDownloader.add(
|
||||
"-b" + Preferences.getInteger("boards." + Preferences.get("board") + ".upload.speed"));
|
||||
commandDownloader.add("-D"); // don't erase
|
||||
commandDownloader.add("-Uflash:w:" + buildPath + File.separator + className + ".hex:i");
|
||||
|
||||
if (Preferences.get("boards." + Preferences.get("board") + ".upload.disable_flushing") == null ||
|
||||
Preferences.getBoolean("boards." + Preferences.get("board") + ".upload.disable_flushing") == false) {
|
||||
flushSerialBuffer();
|
||||
}
|
||||
|
||||
return avrdude(commandDownloader);
|
||||
}
|
||||
|
||||
public boolean burnBootloader(String programmer) throws RunnerException {
|
||||
return burnBootloader(getProgrammerCommands(programmer));
|
||||
}
|
||||
|
||||
private Collection getProgrammerCommands(String programmer) {
|
||||
List params = new ArrayList();
|
||||
params.add("-c" + Preferences.get("programmers." + programmer + ".protocol"));
|
||||
|
||||
if ("usb".equals(Preferences.get("programmers." + programmer + ".communication"))) {
|
||||
params.add("-Pusb");
|
||||
} else if ("serial".equals(Preferences.get("programmers." + programmer + ".communication"))) {
|
||||
params.add("-P" + (Base.isWindows() ? "\\\\.\\" : "") + Preferences.get("serial.port"));
|
||||
// XXX: add support for specifying the baud rate for serial programmers.
|
||||
}
|
||||
// XXX: add support for specifying the port address for parallel
|
||||
// programmers, although avrdude has a default that works in most cases.
|
||||
|
||||
if (Preferences.get("programmers." + programmer + ".force") != null &&
|
||||
Preferences.getBoolean("programmers." + programmer + ".force"))
|
||||
params.add("-F");
|
||||
|
||||
if (Preferences.get("programmers." + programmer + ".delay") != null)
|
||||
params.add("-i" + Preferences.get("programmers." + programmer + ".delay"));
|
||||
|
||||
return params;
|
||||
}
|
||||
|
||||
protected boolean burnBootloader(Collection params)
|
||||
throws RunnerException {
|
||||
List fuses = new ArrayList();
|
||||
fuses.add("-e"); // erase the chip
|
||||
fuses.add("-Ulock:w:" + Preferences.get("boards." + Preferences.get("board") + ".bootloader.unlock_bits") + ":m");
|
||||
if (Preferences.get("boards." + Preferences.get("board") + ".bootloader.extended_fuses") != null)
|
||||
fuses.add("-Uefuse:w:" + Preferences.get("boards." + Preferences.get("board") + ".bootloader.extended_fuses") + ":m");
|
||||
fuses.add("-Uhfuse:w:" + Preferences.get("boards." + Preferences.get("board") + ".bootloader.high_fuses") + ":m");
|
||||
fuses.add("-Ulfuse:w:" + Preferences.get("boards." + Preferences.get("board") + ".bootloader.low_fuses") + ":m");
|
||||
|
||||
if (!avrdude(params, fuses))
|
||||
return false;
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException e) {}
|
||||
|
||||
List bootloader = new ArrayList();
|
||||
bootloader.add("-Uflash:w:" + "hardware" + File.separator + "bootloaders" + File.separator +
|
||||
Preferences.get("boards." + Preferences.get("board") + ".bootloader.path") +
|
||||
File.separator + Preferences.get("boards." + Preferences.get("board") + ".bootloader.file") + ":i");
|
||||
bootloader.add("-Ulock:w:" + Preferences.get("boards." + Preferences.get("board") + ".bootloader.lock_bits") + ":m");
|
||||
|
||||
return avrdude(params, bootloader);
|
||||
}
|
||||
|
||||
public boolean avrdude(Collection p1, Collection p2) throws RunnerException {
|
||||
ArrayList p = new ArrayList(p1);
|
||||
p.addAll(p2);
|
||||
return avrdude(p);
|
||||
}
|
||||
|
||||
public boolean avrdude(Collection params) throws RunnerException {
|
||||
List commandDownloader = new ArrayList();
|
||||
commandDownloader.add("avrdude");
|
||||
|
||||
// Point avrdude at its config file since it's in a non-standard location.
|
||||
if (Base.isLinux()) {
|
||||
// ???: is it better to have Linux users install avrdude themselves, in
|
||||
// a way that it can find its own configuration file?
|
||||
commandDownloader.add("-C" + "hardware/tools/avrdude.conf");
|
||||
} else {
|
||||
commandDownloader.add("-C" + Base.getHardwarePath() + "/tools/avr/etc/avrdude.conf");
|
||||
}
|
||||
|
||||
if (Preferences.getBoolean("upload.verbose")) {
|
||||
commandDownloader.add("-v");
|
||||
commandDownloader.add("-v");
|
||||
commandDownloader.add("-v");
|
||||
commandDownloader.add("-v");
|
||||
} else {
|
||||
commandDownloader.add("-q");
|
||||
commandDownloader.add("-q");
|
||||
}
|
||||
// XXX: quick hack to chop the "atmega" off of "atmega8" and "atmega168",
|
||||
// then shove an "m" at the beginning. won't work for attiny's, etc.
|
||||
commandDownloader.add("-pm" +
|
||||
Preferences.get("boards." + Preferences.get("board") + ".build.mcu").substring(6));
|
||||
commandDownloader.addAll(params);
|
||||
|
||||
return executeUploadCommand(commandDownloader);
|
||||
}
|
||||
}
|
@ -49,10 +49,12 @@ public class Compiler implements MessageConsumer {
|
||||
public Compiler() { }
|
||||
|
||||
/**
|
||||
* Compile with ECJ.
|
||||
* Compile with avr-gcc.
|
||||
*
|
||||
* @param sketch Sketch object to be compiled.
|
||||
* @param buildPath Where the temporary files live and will be built from.
|
||||
* @param primaryClassName the name of the combined sketch file w/ extension
|
||||
* @param target the target (core) to build against
|
||||
* @return true if successful.
|
||||
* @throws RunnerException Only if there's a problem. Only then.
|
||||
*/
|
||||
@ -67,23 +69,13 @@ public class Compiler implements MessageConsumer {
|
||||
// the pms object isn't used for anything but storage
|
||||
MessageStream pms = new MessageStream(this);
|
||||
|
||||
String userdir = System.getProperty("user.dir") + File.separator;
|
||||
|
||||
// LibraryManager libraryManager;
|
||||
//
|
||||
// try {
|
||||
// libraryManager = new LibraryManager();
|
||||
// } catch (IOException e) {
|
||||
// throw new RunnerException(e.getMessage());
|
||||
// }
|
||||
String avrBasePath = Base.getAvrBasePath();
|
||||
|
||||
List includePaths = new ArrayList();
|
||||
includePaths.add(target.getPath());
|
||||
// use lib directories as include paths
|
||||
for (int i = 0; i < sketch.importedLibraries.size(); i++) {
|
||||
includePaths.add(
|
||||
((Library) sketch.importedLibraries.get(i)).getFolder().getPath());
|
||||
for (File file : sketch.getImportedLibraries()) {
|
||||
includePaths.add(file.getPath());
|
||||
}
|
||||
|
||||
List baseCommandLinker = new ArrayList(Arrays.asList(new String[] {
|
||||
@ -95,75 +87,34 @@ public class Compiler implements MessageConsumer {
|
||||
buildPath + File.separator + primaryClassName + ".elf"
|
||||
}));
|
||||
|
||||
String runtimeLibraryName = buildPath + File.separator + "core.a";
|
||||
// String runtimeLibraryName = buildPath + File.separator + "core.a";
|
||||
|
||||
List baseCommandAR = new ArrayList(Arrays.asList(new String[] {
|
||||
avrBasePath + "avr-ar",
|
||||
"rcs",
|
||||
runtimeLibraryName
|
||||
}));
|
||||
// List baseCommandAR = new ArrayList(Arrays.asList(new String[] {
|
||||
// avrBasePath + "avr-ar",
|
||||
// "rcs",
|
||||
// runtimeLibraryName
|
||||
// }));
|
||||
|
||||
// use lib object files
|
||||
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++)
|
||||
baseCommandLinker.add(objectFiles[j].getPath());
|
||||
}
|
||||
|
||||
List baseCommandObjcopy = new ArrayList(Arrays.asList(new String[] {
|
||||
avrBasePath + "avr-objcopy",
|
||||
"-O",
|
||||
"-R",
|
||||
}));
|
||||
|
||||
// make list of code files that need to be compiled and the object files
|
||||
// that they will be compiled to (includes code from the sketch and the
|
||||
// library for the target platform)
|
||||
List sourceNames = new ArrayList();
|
||||
List sourceNamesCPP = new ArrayList();
|
||||
List objectNames = new ArrayList();
|
||||
List objectNamesCPP = new ArrayList();
|
||||
List targetObjectNames = new ArrayList();
|
||||
List sketchObjectNames = new ArrayList();
|
||||
|
||||
sourceNamesCPP.add(buildPath + File.separator + primaryClassName);
|
||||
objectNamesCPP.add(buildPath + File.separator + primaryClassName + ".o");
|
||||
sketchObjectNames.add(buildPath + File.separator + primaryClassName + ".o");
|
||||
ArrayList<File> sourceFiles = new ArrayList<File>();
|
||||
ArrayList<File> sourceFilesCPP = new ArrayList<File>();
|
||||
|
||||
for (int i = 0; i < sketch.getCodeCount(); i++) {
|
||||
//if (sketch.getCode(i).preprocName != null) {
|
||||
if (sketch.getCode(i).isExtension("c")) {
|
||||
sourceNames.add(buildPath + File.separator + sketch.getCode(i).getFileName());
|
||||
objectNames.add(buildPath + File.separator + sketch.getCode(i).getFileName() + ".o");
|
||||
sketchObjectNames.add(buildPath + File.separator + sketch.getCode(i).getFileName() + ".o");
|
||||
} else if (sketch.getCode(i).isExtension("cpp")) {
|
||||
sourceNamesCPP.add(buildPath + File.separator + sketch.getCode(i).getFileName());
|
||||
objectNamesCPP.add(buildPath + File.separator + sketch.getCode(i).getFileName() + ".o");
|
||||
sketchObjectNames.add(buildPath + File.separator + sketch.getCode(i).getFileName() + ".o");
|
||||
}
|
||||
//}
|
||||
}
|
||||
for (Iterator iter = target.getSourceFilenames().iterator(); iter.hasNext(); ) {
|
||||
String filename = (String) iter.next();
|
||||
if (filename != null) {
|
||||
targetObjectNames.add(buildPath + File.separator + filename + ".o");
|
||||
if (filename.endsWith(".c")) {
|
||||
sourceNames.add(target.getPath() + File.separator + filename);
|
||||
objectNames.add(buildPath + File.separator + filename + ".o");
|
||||
} else if (filename.endsWith(".cpp")) {
|
||||
sourceNamesCPP.add(target.getPath() + File.separator + filename);
|
||||
objectNamesCPP.add(buildPath + File.separator + filename + ".o");
|
||||
}
|
||||
}
|
||||
sourceFiles.addAll(findFilesInPath(buildPath, "c", false));
|
||||
sourceFilesCPP.addAll(findFilesInPath(buildPath, "cpp", false));
|
||||
|
||||
sourceFiles.addAll(findFilesInPath(target.getPath(), "c", true));
|
||||
sourceFilesCPP.addAll(findFilesInPath(target.getPath(), "cpp", true));
|
||||
|
||||
for (File file : sketch.getImportedLibraries()) {
|
||||
sourceFiles.addAll(findFilesInFolder(file, "c", true));
|
||||
sourceFilesCPP.addAll(findFilesInFolder(file, "cpp", true));
|
||||
}
|
||||
|
||||
baseCommandLinker.addAll(sketchObjectNames);
|
||||
//baseCommandLinker.addAll(targetObjectNames);
|
||||
baseCommandLinker.add(runtimeLibraryName);
|
||||
baseCommandLinker.add("-L" + buildPath);
|
||||
baseCommandLinker.add("-lm");
|
||||
|
||||
firstErrorFound = false; // haven't found any errors yet
|
||||
secondErrorFound = false;
|
||||
|
||||
@ -175,24 +126,36 @@ public class Compiler implements MessageConsumer {
|
||||
|
||||
Process process;
|
||||
boolean compiling = true;
|
||||
for(int i = 0; i < sourceNames.size(); i++) {
|
||||
for(File file : sourceFiles) {
|
||||
String objectPath = buildPath + File.separator + file.getName() + ".o";
|
||||
baseCommandLinker.add(objectPath);
|
||||
if (execAsynchronously(getCommandCompilerC(avrBasePath, includePaths,
|
||||
(String) sourceNames.get(i), (String) objectNames.get(i))) != 0)
|
||||
file.getAbsolutePath(),
|
||||
objectPath)) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < sourceNamesCPP.size(); i++) {
|
||||
for(File file : sourceFilesCPP) {
|
||||
String objectPath = buildPath + File.separator + file.getName() + ".o";
|
||||
baseCommandLinker.add(objectPath);
|
||||
if (execAsynchronously(getCommandCompilerCPP(avrBasePath, includePaths,
|
||||
(String) sourceNamesCPP.get(i), (String) objectNamesCPP.get(i))) != 0)
|
||||
file.getAbsolutePath(),
|
||||
objectPath)) != 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
for(int i = 0; i < targetObjectNames.size(); i++) {
|
||||
List commandAR = new ArrayList(baseCommandAR);
|
||||
commandAR.add(targetObjectNames.get(i));
|
||||
if (execAsynchronously(commandAR) != 0)
|
||||
return false;
|
||||
}
|
||||
// XXX: DAM: need to assemble the target files together into a library
|
||||
// (.a file) before linking the sketch and libraries against it.
|
||||
// for(File file : findFilesInPath(target.getPath())) {
|
||||
// List commandAR = new ArrayList(baseCommandAR);
|
||||
// commandAR.add(file.getAbsolutePath());
|
||||
// if (execAsynchronously(commandAR) != 0)
|
||||
// return false;
|
||||
// }
|
||||
|
||||
//baseCommandLinker.add(runtimeLibraryName);
|
||||
//baseCommandLinker.add("-L" + buildPath);
|
||||
baseCommandLinker.add("-lm");
|
||||
|
||||
if (execAsynchronously(baseCommandLinker) != 0)
|
||||
return false;
|
||||
@ -513,6 +476,29 @@ public class Compiler implements MessageConsumer {
|
||||
return (new File(path)).list(onlyHFiles);
|
||||
}
|
||||
|
||||
static public ArrayList<File> findFilesInPath(String path, String extension,
|
||||
boolean recurse) {
|
||||
return findFilesInFolder(new File(path), extension, recurse);
|
||||
}
|
||||
|
||||
static public ArrayList<File> findFilesInFolder(File folder, String extension,
|
||||
boolean recurse) {
|
||||
ArrayList<File> files = new ArrayList<File>();
|
||||
|
||||
for (File file : folder.listFiles()) {
|
||||
if (file.getName().equals(".") || file.getName().equals("..")) continue;
|
||||
|
||||
if (file.getName().endsWith("." + extension))
|
||||
files.add(file);
|
||||
|
||||
if (recurse && file.isDirectory()) {
|
||||
files.addAll(findFilesInFolder(file, extension, true));
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a folder, return a list of absolute paths to all jar or zip files
|
||||
* inside that folder, separated by pathSeparatorChar.
|
||||
|
@ -1,595 +0,0 @@
|
||||
/*
|
||||
Library.java - Library System for Wiring
|
||||
Copyright (c) 2006 Nicholas Zambetti. 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
|
||||
*/
|
||||
|
||||
package processing.app.debug;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.syntax.*;
|
||||
import processing.app.debug.RunnerException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
import processing.core.*;
|
||||
|
||||
/*
|
||||
* Provides information about and builds a library
|
||||
*/
|
||||
public class Library implements MessageConsumer{
|
||||
|
||||
private File libFolder;
|
||||
private File utilityFolder;
|
||||
private LibraryManager libManager;
|
||||
RunnerException exception;
|
||||
|
||||
static final String BUGS_URL = "https://developer.berlios.de/bugs/?group_id=3590";
|
||||
static final String SUPER_BADNESS = "Compiler error, please submit this code to " + BUGS_URL;
|
||||
|
||||
/*
|
||||
* Create a Library
|
||||
*/
|
||||
public Library(LibraryManager manager, File folder)
|
||||
{
|
||||
libFolder = folder;
|
||||
libManager = manager;
|
||||
utilityFolder = getUtilityFolder();
|
||||
|
||||
// for debug output
|
||||
/*
|
||||
System.out.println("library: " + getName());
|
||||
System.out.println("folder: " + getFolder());
|
||||
System.out.println("utility: " + utilityFolder);
|
||||
System.out.println("built: " + isBuilt());
|
||||
System.out.println("buildable: " + isBuildable());
|
||||
System.out.println("o files: " + getObjectFiles().length);
|
||||
System.out.println("c files: " + getCSourceFiles().length);
|
||||
System.out.println("cpp files: " + getCPPSourceFiles().length);
|
||||
*/
|
||||
}
|
||||
|
||||
/*
|
||||
* Directory of library
|
||||
* @return File object of library's folder
|
||||
*/
|
||||
public File getFolder()
|
||||
{
|
||||
return libFolder;
|
||||
}
|
||||
|
||||
/*
|
||||
* The name of library
|
||||
* @return String with library name, derived from folder
|
||||
* note: this will be eventually taken from xml description file
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return libFolder.getName();
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests if library is built
|
||||
* @return True if library has .o files, false otherwise
|
||||
*/
|
||||
public boolean isBuilt()
|
||||
{
|
||||
if(getObjectFiles().length >= (getCSourceFiles().length + getCPPSourceFiles().length)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests if library is buildable
|
||||
* @return True if library has source files, false otherwise
|
||||
*/
|
||||
public boolean isBuildable()
|
||||
{
|
||||
if(0 < (getCSourceFiles().length + getCPPSourceFiles().length)){
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Tests if library is unbuilt but buildable
|
||||
* @return True if library has .cpp files but no .o files, false otherwise
|
||||
*/
|
||||
public boolean isUnbuiltBuildable()
|
||||
{
|
||||
if(isBuildable()){
|
||||
if(!isBuilt()){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans for library "utility" folder
|
||||
* @return File object of library's "utility" folder, or null
|
||||
*/
|
||||
private File getUtilityFolder()
|
||||
{
|
||||
FileFilter filter = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
if(file.isDirectory()){
|
||||
if((file.getName()).equalsIgnoreCase("utility")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
File[] files = libFolder.listFiles(filter);
|
||||
if(files.length > 0){
|
||||
return files[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Finds examples folder
|
||||
* @return "examples" folder as file object or null
|
||||
*/
|
||||
private File getExamplesFolder()
|
||||
{
|
||||
FileFilter filter = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
if(file.isDirectory()){
|
||||
if((file.getName()).equalsIgnoreCase("examples")){
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
File[] files = libFolder.listFiles(filter);
|
||||
if(files.length > 0){
|
||||
return files[0];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates example menu or submenu with files
|
||||
*/
|
||||
private void populateWithExamples(File folder, JMenu menu, ActionListener listener) {
|
||||
FileFilter onlyfolders = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory();
|
||||
}
|
||||
};
|
||||
File[] folders = folder.listFiles(onlyfolders);
|
||||
File file;
|
||||
JMenu submenu;
|
||||
JMenuItem item;
|
||||
for(int i = 0; i < folders.length; ++i){
|
||||
file = new File(folders[i], folders[i].getName() + ".pde");
|
||||
if(file.exists()){
|
||||
item = new JMenuItem(folders[i].getName());
|
||||
item.setActionCommand(file.getAbsolutePath());
|
||||
item.addActionListener(listener);
|
||||
menu.add(item);
|
||||
}else{
|
||||
submenu = new JMenu(folders[i].getName());
|
||||
populateWithExamples(folders[i], submenu, listener);
|
||||
menu.add(submenu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds and returns an examples menu
|
||||
* @return JMenu object with example files, or null if none
|
||||
*/
|
||||
public JMenu getExamplesMenu(ActionListener listener) {
|
||||
JMenu submenu;
|
||||
File examplesFolder = getExamplesFolder();
|
||||
if(null != examplesFolder){
|
||||
submenu = new JMenu("Library-" + getName());
|
||||
populateWithExamples(examplesFolder, submenu, listener);
|
||||
return submenu;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of object files for linking
|
||||
* @return Array of object files as File objects
|
||||
*/
|
||||
private File[] getObjectFiles(File folder)
|
||||
{
|
||||
FileFilter onlyObjectFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".o");
|
||||
}
|
||||
};
|
||||
return folder.listFiles(onlyObjectFiles);
|
||||
}
|
||||
public File[] getObjectFiles()
|
||||
{
|
||||
if(null == utilityFolder){
|
||||
return getObjectFiles(libFolder);
|
||||
}
|
||||
File[] libraryObjects = getObjectFiles(libFolder);
|
||||
File[] utilityObjects = getObjectFiles(utilityFolder);
|
||||
File[] objects = new File[libraryObjects.length + utilityObjects.length];
|
||||
System.arraycopy(libraryObjects, 0, objects, 0, libraryObjects.length);
|
||||
System.arraycopy(utilityObjects, 0, objects, libraryObjects.length, utilityObjects.length);
|
||||
return objects;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of header source files for inclusion
|
||||
* @return Array of header source files as File objects
|
||||
*/
|
||||
public File[] getHeaderFiles()
|
||||
{
|
||||
FileFilter onlyHFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".h");
|
||||
}
|
||||
};
|
||||
return libFolder.listFiles(onlyHFiles);
|
||||
}
|
||||
|
||||
/*
|
||||
* List of library's C source files for compiling
|
||||
* @return Array of C source files as File objects
|
||||
*/
|
||||
private File[] getCSourceFiles(File folder)
|
||||
{
|
||||
FileFilter onlyCFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".c");
|
||||
}
|
||||
};
|
||||
return folder.listFiles(onlyCFiles);
|
||||
}
|
||||
private File[] getCSourceFiles()
|
||||
{
|
||||
if(null == utilityFolder){
|
||||
return getCSourceFiles(libFolder);
|
||||
}
|
||||
File[] librarySources = getCSourceFiles(libFolder);
|
||||
File[] utilitySources = getCSourceFiles(utilityFolder);
|
||||
File[] sources = new File[librarySources.length + utilitySources.length];
|
||||
System.arraycopy(librarySources, 0, sources, 0, librarySources.length);
|
||||
System.arraycopy(utilitySources, 0, sources, librarySources.length, utilitySources.length);
|
||||
return sources;
|
||||
}
|
||||
|
||||
/*
|
||||
* List of C++ source files for compiling
|
||||
* @return Array of C++ source files as File objects
|
||||
*/
|
||||
private File[] getCPPSourceFiles(File folder)
|
||||
{
|
||||
FileFilter onlyCPPFiles = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return (file.getName()).endsWith(".cpp");
|
||||
}
|
||||
};
|
||||
return folder.listFiles(onlyCPPFiles);
|
||||
}
|
||||
private File[] getCPPSourceFiles()
|
||||
{
|
||||
if(null == utilityFolder){
|
||||
return getCPPSourceFiles(libFolder);
|
||||
}
|
||||
File[] librarySources = getCPPSourceFiles(libFolder);
|
||||
File[] utilitySources = getCPPSourceFiles(utilityFolder);
|
||||
File[] sources = new File[librarySources.length + utilitySources.length];
|
||||
System.arraycopy(librarySources, 0, sources, 0, librarySources.length);
|
||||
System.arraycopy(utilitySources, 0, sources, librarySources.length, utilitySources.length);
|
||||
return sources;
|
||||
}
|
||||
|
||||
/*
|
||||
* Attempt to build library
|
||||
* @return true on successful build, false otherwise
|
||||
*/
|
||||
public boolean build() throws RunnerException
|
||||
{
|
||||
// fail if library is not buildable (contains no sources)
|
||||
if(!isBuildable()){
|
||||
return false;
|
||||
}
|
||||
|
||||
String userdir = System.getProperty("user.dir") + File.separator;
|
||||
String avrBasePath;
|
||||
if(Base.isMacOS()) {
|
||||
avrBasePath = new String("hardware/tools/avr/bin/");
|
||||
}
|
||||
else if(Base.isLinux()) {
|
||||
avrBasePath = new String("");
|
||||
}
|
||||
else {
|
||||
avrBasePath = new String(userdir + "hardware/tools/avr/bin/");
|
||||
}
|
||||
|
||||
String[] baseCompileCommandC = new String[] {
|
||||
avrBasePath + "avr-gcc",
|
||||
"-c",
|
||||
"-g",
|
||||
"-Os",
|
||||
"-Wall",
|
||||
"-ffunction-sections", // place each function in its own section
|
||||
"-fdata-sections",
|
||||
"-mmcu=" + Preferences.get("boards." + Preferences.get("board") + ".build.mcu"),
|
||||
"-DF_CPU=" + Preferences.get("boards." + Preferences.get("board") + ".build.f_cpu"),
|
||||
"-I" + libManager.getTarget().getPath(),
|
||||
"-I" + getFolder(),
|
||||
};
|
||||
|
||||
String[] baseCompileCommandCPP = new String[] {
|
||||
avrBasePath + "avr-g++",
|
||||
"-c",
|
||||
"-g",
|
||||
"-Os",
|
||||
"-Wall",
|
||||
"-fno-exceptions",
|
||||
"-ffunction-sections", // place each function in its own section
|
||||
"-fdata-sections",
|
||||
"-mmcu=" + Preferences.get("boards." + Preferences.get("board") + ".build.mcu"),
|
||||
"-DF_CPU=" + Preferences.get("boards." + Preferences.get("board") + ".build.f_cpu"),
|
||||
"-I" + libManager.getTarget().getPath(),
|
||||
"-I" + getFolder(),
|
||||
};
|
||||
|
||||
// use built lib directories in include paths when searching for headers
|
||||
// this allows libs to use other libs easily
|
||||
int extraSpots = 2; // two spots for file path and -o portions
|
||||
utilityFolder = getUtilityFolder(); // refresh status of utility folder
|
||||
if(null != utilityFolder){
|
||||
extraSpots = 3; // an extra spot for utility folder as include
|
||||
}
|
||||
String[] libDirs = libManager.getFolderPaths();
|
||||
String[] compileCommandC = new String[baseCompileCommandC.length + libDirs.length + extraSpots];
|
||||
String[] compileCommandCPP = new String[baseCompileCommandCPP.length + libDirs.length + extraSpots];
|
||||
System.arraycopy(baseCompileCommandC, 0, compileCommandC, 0, baseCompileCommandC.length);
|
||||
System.arraycopy(baseCompileCommandCPP, 0, compileCommandCPP, 0, baseCompileCommandCPP.length);
|
||||
for (int i = 0; i < libDirs.length; ++i) {
|
||||
compileCommandC[baseCompileCommandC.length + i] = "-I" + libDirs[i];
|
||||
compileCommandCPP[baseCompileCommandCPP.length + i] = "-I" + libDirs[i];
|
||||
}
|
||||
|
||||
// add this library's "utility" folder to inclusion paths
|
||||
if(null != utilityFolder){
|
||||
compileCommandC[compileCommandC.length - 3] = "-I" + utilityFolder.getPath();
|
||||
compileCommandCPP[compileCommandCPP.length - 3] = "-I" + utilityFolder.getPath();
|
||||
}
|
||||
|
||||
File[] sourcesC = getCSourceFiles();
|
||||
File[] sourcesCPP = getCPPSourceFiles();
|
||||
|
||||
// execute the compiler, and create threads to deal
|
||||
// with the input and error streams
|
||||
//
|
||||
int result = 0;
|
||||
try {
|
||||
String pathSansExtension;
|
||||
Process process;
|
||||
boolean compiling = true;
|
||||
|
||||
// compile c sources
|
||||
for(int i = 0; i < sourcesC.length; ++i) {
|
||||
pathSansExtension = sourcesC[i].getPath();
|
||||
pathSansExtension = pathSansExtension.substring(0, pathSansExtension.length() - 2); // -2 because ".c"
|
||||
|
||||
compileCommandC[compileCommandC.length - 2] = sourcesC[i].getPath();
|
||||
compileCommandC[compileCommandC.length - 1] = "-o" + pathSansExtension + ".o";
|
||||
|
||||
process = Runtime.getRuntime().exec(compileCommandC);
|
||||
new MessageSiphon(process.getInputStream(), this);
|
||||
new MessageSiphon(process.getErrorStream(), this);
|
||||
|
||||
// wait for the process to finish. if interrupted
|
||||
// before waitFor returns, continue waiting
|
||||
//
|
||||
compiling = true;
|
||||
while (compiling) {
|
||||
try {
|
||||
result = process.waitFor();
|
||||
//System.out.println("result is " + result);
|
||||
compiling = false;
|
||||
} catch (InterruptedException ignored) { }
|
||||
}
|
||||
if (exception != null) {
|
||||
//exception.hideStackTrace = true;
|
||||
throw exception;
|
||||
}
|
||||
if(result != 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// compile c++ sources
|
||||
for(int i = 0; i < sourcesCPP.length; ++i) {
|
||||
pathSansExtension = sourcesCPP[i].getPath();
|
||||
pathSansExtension = pathSansExtension.substring(0, pathSansExtension.length() - 4); // -4 because ".cpp"
|
||||
|
||||
compileCommandCPP[compileCommandCPP.length - 2] = sourcesCPP[i].getPath();
|
||||
compileCommandCPP[compileCommandCPP.length - 1] = "-o" + pathSansExtension + ".o";
|
||||
|
||||
process = Runtime.getRuntime().exec(compileCommandCPP);
|
||||
new MessageSiphon(process.getInputStream(), this);
|
||||
new MessageSiphon(process.getErrorStream(), this);
|
||||
|
||||
// wait for the process to finish. if interrupted
|
||||
// before waitFor returns, continue waiting
|
||||
//
|
||||
compiling = true;
|
||||
while (compiling) {
|
||||
try {
|
||||
result = process.waitFor();
|
||||
//System.out.println("result is " + result);
|
||||
compiling = false;
|
||||
} catch (InterruptedException ignored) { }
|
||||
}
|
||||
if (exception != null) {
|
||||
//exception.hideStackTrace = true;
|
||||
throw exception;
|
||||
}
|
||||
if(result != 0){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
if ((msg != null) && (msg.indexOf("avr-gcc: not found") != -1)) {
|
||||
Base.showWarning("Compiler error",
|
||||
"Could not find the compiler.\n" +
|
||||
"avr-gcc is missing from your PATH,\n" +
|
||||
"see readme.txt for help.", null);
|
||||
return false;
|
||||
|
||||
} else if ((msg != null) && (msg.indexOf("avr-g++: not found") != -1)) {
|
||||
Base.showWarning("Compiler error",
|
||||
"Could not find the compiler.\n" +
|
||||
"avr-g++ is missing from your PATH,\n" +
|
||||
"see readme.txt for help.", null);
|
||||
return false;
|
||||
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// an error was queued up by message()
|
||||
if (exception != null) {
|
||||
throw exception;
|
||||
}
|
||||
|
||||
if (result != 0 && result != 1 ) {
|
||||
Base.openURL(BUGS_URL);
|
||||
throw new RunnerException(SUPER_BADNESS);
|
||||
}
|
||||
|
||||
// success would mean that 'result' is set to zero
|
||||
return (result == 0); // ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Part of the MessageConsumer interface, this is called
|
||||
* whenever a piece (usually a line) of error message is spewed
|
||||
* out from the compiler. The errors are parsed for their contents
|
||||
* and line number, which is then reported back to Editor.
|
||||
*/
|
||||
public void message(String inString) {
|
||||
// This receives messages as full lines, so a newline needs
|
||||
// to be added as they're printed to the console.
|
||||
|
||||
// always print all compilation output for library writers!
|
||||
String outString = "";
|
||||
|
||||
// shorten file paths so that they are friendlier
|
||||
int start = 0;
|
||||
int end = 0;
|
||||
String substring = libFolder.getPath() + File.separator;
|
||||
StringBuffer result = new StringBuffer();
|
||||
while ((end = inString.indexOf(substring, start)) >= 0) {
|
||||
result.append(inString.substring(start, end));
|
||||
start = end + substring.length();
|
||||
}
|
||||
result.append(inString.substring(start));
|
||||
outString = result.toString();
|
||||
|
||||
System.err.print(outString);
|
||||
|
||||
// prepare error for throwing
|
||||
if (inString.indexOf("error") != -1){
|
||||
exception = new RunnerException("Error building library \"" + getName() + "\"");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles loading of keywords file.
|
||||
* It is recommended that a # sign be used for comments
|
||||
* inside keywords.txt.
|
||||
*/
|
||||
public void addSyntaxColors(PdeKeywords keywords) {
|
||||
File keywordsFile = new File(libFolder.getPath() + File.separator + "keywords.txt");
|
||||
|
||||
// do not bother if no keywords file to read
|
||||
// should reprimand negligent library writers?!
|
||||
if(!keywordsFile.exists() || !keywordsFile.canRead()){
|
||||
return;
|
||||
}
|
||||
|
||||
try{
|
||||
// open file stream in the verbose java way
|
||||
InputStream input = new FileInputStream(keywordsFile);
|
||||
InputStreamReader isr = new InputStreamReader(input);
|
||||
BufferedReader reader = new BufferedReader(isr);
|
||||
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
|
||||
// skip empty and whitespace lines
|
||||
if (line.trim().length() == 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
// skip lines without tabs
|
||||
if (line.indexOf('\t') == -1){
|
||||
continue;
|
||||
}
|
||||
|
||||
String pieces[] = PApplet.split(line, '\t');
|
||||
|
||||
if (pieces.length >= 2) {
|
||||
String keyword = pieces[0].trim();
|
||||
String coloring = pieces[1].trim();
|
||||
|
||||
if (coloring.length() > 0) {
|
||||
// text will be KEYWORD or LITERAL
|
||||
boolean isKey = (coloring.charAt(0) == 'K');
|
||||
|
||||
// KEYWORD1 -> 0, KEYWORD2 -> 1, etc
|
||||
int num = coloring.charAt(coloring.length() - 1) - '1';
|
||||
|
||||
byte id = (byte)((isKey ? Token.KEYWORD1 : Token.LITERAL1) + num);
|
||||
|
||||
//System.out.println("got " + (isKey ? "keyword" : "literal") + (num+1) + " for " + keyword);
|
||||
|
||||
// XXX: DAM: PdeKeywords.getKeywordColoring().add(keyword, id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// close file stream
|
||||
reader.close();
|
||||
} catch (Exception e) {
|
||||
Base.showError("Problem Loading Keywords",
|
||||
"Could not load or interpret 'keywords.txt' in " + getName() + " library.\n" +
|
||||
"This must be corrected before distributing.", e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -1,274 +0,0 @@
|
||||
/*
|
||||
LibraryManager.java - Library System for Wiring
|
||||
Copyright (c) 2006-07 Nicholas Zambetti. 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
|
||||
*/
|
||||
|
||||
package processing.app.debug;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.syntax.*;
|
||||
import processing.app.debug.RunnerException;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
|
||||
import java.awt.event.*;
|
||||
|
||||
import javax.swing.*;
|
||||
|
||||
/*
|
||||
* Provides information about and builds libraries
|
||||
*/
|
||||
public class LibraryManager {
|
||||
|
||||
private File libDir;
|
||||
private List libraries = new ArrayList();
|
||||
private Target target;
|
||||
|
||||
/*
|
||||
* Create a LibraryManager.
|
||||
*/
|
||||
public LibraryManager() throws IOException
|
||||
{
|
||||
String userDir = System.getProperty("user.dir") + File.separator;
|
||||
libDir = new File(Base.getHardwareFolder(), "libraries");
|
||||
// target = new Target(
|
||||
// System.getProperty("user.dir") + File.separator + "hardware" +
|
||||
// File.separator + "cores",
|
||||
// Preferences.get("boards." + Preferences.get("board") + ".build.core"));
|
||||
target = new Target(Base.getHardwarePath() + File.separator + "cores",
|
||||
"arduino");
|
||||
refreshLibraries();
|
||||
}
|
||||
|
||||
public Target getTarget()
|
||||
{
|
||||
return target;
|
||||
}
|
||||
|
||||
/*
|
||||
* Scans for libraries and refreshes internal list
|
||||
*/
|
||||
private void refreshLibraries()
|
||||
{
|
||||
FileFilter onlyDirs = new FileFilter() {
|
||||
public boolean accept(File file) {
|
||||
return file.isDirectory();
|
||||
}
|
||||
};
|
||||
libraries.clear();
|
||||
File[] libs = libDir.listFiles(onlyDirs);
|
||||
for(int i = 0; i < libs.length; ++i){
|
||||
libraries.add(new Library(this, libs[i]));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a collection of all library objects
|
||||
* @return A read-only collection of Library objects
|
||||
*/
|
||||
public Collection getAll() {
|
||||
refreshLibraries();
|
||||
return Collections.unmodifiableList(libraries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a collection of all built library objects
|
||||
* @return A read-only collection of built Library objects
|
||||
*/
|
||||
public Collection getBuiltLibraries() {
|
||||
refreshLibraries();
|
||||
List builtLibraries = new ArrayList();
|
||||
Library library;
|
||||
ListIterator libIterator = libraries.listIterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
if(library.isBuilt()){
|
||||
builtLibraries.add(library);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(builtLibraries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns a collection of all buildable library objects
|
||||
* @return A read-only collection of built Library objects
|
||||
*/
|
||||
public Collection getLibrariesToBuild() {
|
||||
refreshLibraries();
|
||||
List buildableLibraries = new ArrayList();
|
||||
Library library;
|
||||
ListIterator libIterator = libraries.listIterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
if(library.isUnbuiltBuildable()){
|
||||
buildableLibraries.add(library);
|
||||
}
|
||||
}
|
||||
return Collections.unmodifiableList(buildableLibraries);
|
||||
}
|
||||
|
||||
/*
|
||||
* Rebuilds built libraries
|
||||
* @return Number of libraries built as int, -1 & exception on error
|
||||
*/
|
||||
public int rebuildAllBuilt() throws RunnerException {
|
||||
Collection builtLibraries = getBuiltLibraries();
|
||||
Library library;
|
||||
Iterator libIterator = builtLibraries.iterator();
|
||||
int countBuilt = 0;
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
//System.out.println("Building library \"" + library.getName() + "\"");
|
||||
try {
|
||||
if(library.build()){
|
||||
++countBuilt;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}catch (RunnerException re) {
|
||||
throw new RunnerException(re.getMessage());
|
||||
} catch (Exception ex) {
|
||||
throw new RunnerException(ex.toString());
|
||||
}
|
||||
}
|
||||
return countBuilt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gathers paths to object files
|
||||
* @return Array of strings of paths to object files
|
||||
*/
|
||||
public String[] getObjectFiles() {
|
||||
ArrayList filesArrayList = new ArrayList();
|
||||
Collection builtLibraries = getBuiltLibraries();
|
||||
Library library;
|
||||
File[] files;
|
||||
Iterator libIterator = builtLibraries.iterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
files = library.getObjectFiles();
|
||||
for(int i = 0; i < files.length; ++i){
|
||||
filesArrayList.add(files[i].getPath());
|
||||
}
|
||||
}
|
||||
String[] filesArray = new String[filesArrayList.size()];
|
||||
filesArrayList.toArray(filesArray);
|
||||
return filesArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gathers filenames of header files
|
||||
* @return Array of strings of filenames of header files
|
||||
*/
|
||||
public String[] getHeaderFiles() {
|
||||
ArrayList filesArrayList = new ArrayList();
|
||||
Collection builtLibraries = getBuiltLibraries();
|
||||
Library library;
|
||||
File[] files;
|
||||
Iterator libIterator = builtLibraries.iterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
files = library.getHeaderFiles();
|
||||
for(int i = 0; i < files.length; ++i){
|
||||
filesArrayList.add(files[i].getName());
|
||||
}
|
||||
}
|
||||
String[] filesArray = new String[filesArrayList.size()];
|
||||
filesArrayList.toArray(filesArray);
|
||||
return filesArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Gathers paths to library folders
|
||||
* @return Array of strings of paths to library folders
|
||||
*/
|
||||
public String[] getFolderPaths() {
|
||||
ArrayList foldersArrayList = new ArrayList();
|
||||
//Collection builtLibraries = getBuiltLibraries();
|
||||
Collection libraries = getAll();
|
||||
Library library;
|
||||
//Iterator libIterator = builtLibraries.iterator();
|
||||
Iterator libIterator = libraries.iterator();
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
foldersArrayList.add(library.getFolder().getPath());
|
||||
}
|
||||
String[] foldersArray = new String[foldersArrayList.size()];
|
||||
foldersArrayList.toArray(foldersArray);
|
||||
return foldersArray;
|
||||
}
|
||||
|
||||
/*
|
||||
* Builds unbuilt libraries
|
||||
* @return Number of libraries built as int, -1 & exception on error
|
||||
*/
|
||||
public int buildAllUnbuilt() throws RunnerException {
|
||||
Collection buildableLibraries = getLibrariesToBuild();
|
||||
Library library;
|
||||
Iterator libIterator = buildableLibraries.iterator();
|
||||
int countBuilt = 0;
|
||||
while(libIterator.hasNext()){
|
||||
library = (Library)libIterator.next();
|
||||
//System.out.println("Building library \"" + library.getName() + "\"");
|
||||
try {
|
||||
if(library.build()){
|
||||
++countBuilt;
|
||||
}else{
|
||||
return -1;
|
||||
}
|
||||
}catch (RunnerException re) {
|
||||
throw new RunnerException(re.getMessage());
|
||||
} catch (Exception ex) {
|
||||
throw new RunnerException(ex.toString());
|
||||
}
|
||||
}
|
||||
return countBuilt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Populates examples menu with library folders
|
||||
*/
|
||||
public void populateExamplesMenu(JMenu examplesMenu, ActionListener listener) {
|
||||
Library library;
|
||||
Collection libraries = getBuiltLibraries();
|
||||
Iterator iterator = libraries.iterator();
|
||||
JMenu libraryExamples;
|
||||
while(iterator.hasNext()){
|
||||
library = (Library)iterator.next();
|
||||
libraryExamples = library.getExamplesMenu(listener);
|
||||
if(null != libraryExamples){
|
||||
examplesMenu.add(libraryExamples);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Add syntax coloring
|
||||
*/
|
||||
public void addSyntaxColoring(PdeKeywords keywords) {
|
||||
Library library;
|
||||
Collection libraries = getBuiltLibraries();
|
||||
Iterator iterator = libraries.iterator();
|
||||
while(iterator.hasNext()){
|
||||
library = (Library)iterator.next();
|
||||
library.addSyntaxColors(keywords);
|
||||
}
|
||||
}
|
||||
}
|
220
app/src/processing/app/debug/Uploader.java
Executable file
220
app/src/processing/app/debug/Uploader.java
Executable file
@ -0,0 +1,220 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
|
||||
/*
|
||||
Uploader - abstract uploading baseclass (common to both uisp and avrdude)
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2004-05
|
||||
Hernando Barragan
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program 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 General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
|
||||
$Id$
|
||||
*/
|
||||
|
||||
package processing.app.debug;
|
||||
|
||||
import processing.app.Base;
|
||||
import processing.app.Preferences;
|
||||
import processing.app.Serial;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.*;
|
||||
import javax.swing.*;
|
||||
//#ifndef RXTX
|
||||
//import javax.comm.*;
|
||||
//#else
|
||||
// rxtx uses package gnu.io, but all the class names
|
||||
// are the same as those used by javax.comm
|
||||
import gnu.io.*;
|
||||
//#endif
|
||||
|
||||
|
||||
public abstract class Uploader implements MessageConsumer {
|
||||
static final String BUGS_URL =
|
||||
"https://developer.berlios.de/bugs/?group_id=3590";
|
||||
static final String SUPER_BADNESS =
|
||||
"Compiler error, please submit this code to " + BUGS_URL;
|
||||
|
||||
RunnerException exception;
|
||||
//PdePreferences preferences;
|
||||
|
||||
//Serial serialPort;
|
||||
static InputStream serialInput;
|
||||
static OutputStream serialOutput;
|
||||
//int serial; // last byte of data received
|
||||
|
||||
public Uploader() {
|
||||
}
|
||||
|
||||
public abstract boolean uploadUsingPreferences(String buildPath, String className)
|
||||
throws RunnerException;
|
||||
|
||||
public abstract boolean burnBootloader(String programmer) throws RunnerException;
|
||||
|
||||
protected void flushSerialBuffer() throws RunnerException {
|
||||
// Cleanup the serial buffer
|
||||
try {
|
||||
Serial serialPort = new Serial();
|
||||
byte[] readBuffer;
|
||||
while(serialPort.available() > 0) {
|
||||
readBuffer = serialPort.readBytes();
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {}
|
||||
}
|
||||
|
||||
serialPort.setDTR(false);
|
||||
|
||||
try {
|
||||
Thread.sleep(100);
|
||||
} catch (InterruptedException e) {}
|
||||
|
||||
serialPort.setDTR(true);
|
||||
|
||||
serialPort.dispose();
|
||||
} catch(Exception e) {
|
||||
e.printStackTrace();
|
||||
throw new RunnerException(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
protected boolean executeUploadCommand(Collection commandDownloader)
|
||||
throws RunnerException
|
||||
{
|
||||
firstErrorFound = false; // haven't found any errors yet
|
||||
secondErrorFound = false;
|
||||
notFoundError = false;
|
||||
int result=0; // pre-initialized to quiet a bogus warning from jikes
|
||||
|
||||
String userdir = System.getProperty("user.dir") + File.separator;
|
||||
|
||||
try {
|
||||
String[] commandArray = new String[commandDownloader.size()];
|
||||
commandDownloader.toArray(commandArray);
|
||||
|
||||
String avrBasePath;
|
||||
|
||||
if(Base.isLinux()) {
|
||||
avrBasePath = new String(Base.getHardwarePath() + "/tools/");
|
||||
}
|
||||
else {
|
||||
avrBasePath = new String(Base.getHardwarePath() + "/tools/avr/bin/");
|
||||
}
|
||||
|
||||
commandArray[0] = avrBasePath + commandArray[0];
|
||||
|
||||
if (Preferences.getBoolean("upload.verbose")) {
|
||||
for(int i = 0; i < commandArray.length; i++) {
|
||||
System.out.print(commandArray[i] + " ");
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
Process process = Runtime.getRuntime().exec(commandArray);
|
||||
new MessageSiphon(process.getInputStream(), this);
|
||||
new MessageSiphon(process.getErrorStream(), this);
|
||||
|
||||
// wait for the process to finish. if interrupted
|
||||
// before waitFor returns, continue waiting
|
||||
//
|
||||
boolean compiling = true;
|
||||
while (compiling) {
|
||||
try {
|
||||
result = process.waitFor();
|
||||
compiling = false;
|
||||
} catch (InterruptedException intExc) {
|
||||
}
|
||||
}
|
||||
if(exception!=null) {
|
||||
exception.hideStackTrace();
|
||||
throw exception;
|
||||
}
|
||||
if(result!=0)
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
String msg = e.getMessage();
|
||||
if ((msg != null) && (msg.indexOf("uisp: not found") != -1) && (msg.indexOf("avrdude: not found") != -1)) {
|
||||
//System.err.println("uisp is missing");
|
||||
//JOptionPane.showMessageDialog(editor.base,
|
||||
// "Could not find the compiler.\n" +
|
||||
// "uisp is missing from your PATH,\n" +
|
||||
// "see readme.txt for help.",
|
||||
// "Compiler error",
|
||||
// JOptionPane.ERROR_MESSAGE);
|
||||
return false;
|
||||
} else {
|
||||
e.printStackTrace();
|
||||
result = -1;
|
||||
}
|
||||
}
|
||||
//System.out.println("result2 is "+result);
|
||||
// if the result isn't a known, expected value it means that something
|
||||
// is fairly wrong, one possibility is that jikes has crashed.
|
||||
//
|
||||
if (exception != null) throw exception;
|
||||
|
||||
if ((result != 0) && (result != 1 )) {
|
||||
exception = new RunnerException(SUPER_BADNESS);
|
||||
//editor.error(exception);
|
||||
//PdeBase.openURL(BUGS_URL);
|
||||
//throw new PdeException(SUPER_BADNESS);
|
||||
}
|
||||
|
||||
return (result == 0); // ? true : false;
|
||||
|
||||
}
|
||||
|
||||
boolean firstErrorFound;
|
||||
boolean secondErrorFound;
|
||||
|
||||
// part of the PdeMessageConsumer interface
|
||||
//
|
||||
boolean notFoundError;
|
||||
|
||||
public void message(String s) {
|
||||
//System.err.println("MSG: " + s);
|
||||
System.err.print(s);
|
||||
|
||||
// ignore cautions
|
||||
if (s.indexOf("Error") != -1) {
|
||||
//exception = new RunnerException(s+" Check the serial port selected or your Board is connected");
|
||||
//System.out.println(s);
|
||||
notFoundError = true;
|
||||
return;
|
||||
}
|
||||
if(notFoundError) {
|
||||
//System.out.println("throwing something");
|
||||
exception = new RunnerException("the selected serial port "+s+" does not exist or your board is not connected");
|
||||
return;
|
||||
}
|
||||
if (s.indexOf("Device is not responding") != -1 ) {
|
||||
exception = new RunnerException("Device is not responding, check the right serial port is selected or RESET the board right before exporting");
|
||||
return;
|
||||
}
|
||||
if (s.indexOf("Programmer is not responding") != -1 ||
|
||||
s.indexOf("programmer is not responding") != -1 ||
|
||||
s.indexOf("protocol error") != -1) {
|
||||
exception = new RunnerException("Problem uploading to board. See http://www.arduino.cc/en/Guide/Troubleshooting#upload for suggestions.");
|
||||
return;
|
||||
}
|
||||
if (s.indexOf("Expected signature") != -1) {
|
||||
exception = new RunnerException("Wrong microcontroller found. Did you select the right board from the Tools > Board menu?");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -68,7 +68,7 @@
|
||||
<!-- In 0149, removed /System/Library/Java from the CLASSPATH because
|
||||
it can cause problems if users have installed weird files there.
|
||||
http://dev.processing.org/bugs/show_bug.cgi?id=1045 -->
|
||||
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/oro.jar</string>
|
||||
<string>$JAVAROOT/pde.jar:$JAVAROOT/core.jar:$JAVAROOT/antlr.jar:$JAVAROOT/ecj.jar:$JAVAROOT/registry.jar:$JAVAROOT/quaqua.jar:$JAVAROOT/oro.jar:$JAVAROOT/RXTXcomm.jar</string>
|
||||
|
||||
<key>Properties</key>
|
||||
<dict>
|
||||
|
@ -34,6 +34,7 @@ else
|
||||
cp -X ../../app/lib/ecj.jar "$RESOURCES/"
|
||||
cp -X ../../app/lib/jna.jar "$RESOURCES/"
|
||||
cp -X ../../app/lib/oro.jar "$RESOURCES/"
|
||||
cp -X ../../app/lib/RXTXcomm.jar "$RESOURCES/"
|
||||
|
||||
echo Copying examples...
|
||||
cp -r ../shared/examples "$RESOURCES/"
|
||||
@ -102,7 +103,7 @@ mkdir ../build/macosx/work/classes
|
||||
javac \
|
||||
-Xlint:deprecation \
|
||||
-source 1.5 -target 1.5 \
|
||||
-classpath "$RESOURCES/core.jar:$RESOURCES/antlr.jar:$RESOURCES/ecj.jar:$RESOURCES/jna.jar:$RESOURCES/oro.jar" \
|
||||
-classpath "$RESOURCES/core.jar:$RESOURCES/antlr.jar:$RESOURCES/ecj.jar:$RESOURCES/jna.jar:$RESOURCES/oro.jar:$RESOURCES/RXTXcomm.jar" \
|
||||
-d ../build/macosx/work/classes \
|
||||
src/processing/app/*.java \
|
||||
src/processing/app/debug/*.java \
|
||||
|
Loading…
x
Reference in New Issue
Block a user