mirror of
https://github.com/esp8266/Arduino.git
synced 2025-08-11 09:43:08 +03:00
Merge branch 'master' into esp8266
* master: (414 commits) Don't export sketch if the underlying core does not support it. Fixes #3171 RSyntaxTextArea: using a modified version, tracked at https://github.com/arduino/RSyntaxTextArea. Fixes #3099 Updated keywords.txt New editor on MacOSX: since CMD+J is known as "jump to selection" and the editor has no such feature, CMD+J is disabled on mac. See #3098 Old Preferences class remains for backwards compatibility as a delegate for PreferencesData New Preferences window: renders fine on every OS and it's easier to adapt using NetBeans as visual editor. Fixes #3140 Remove spawn from exec command Removed redundant call to File.deleteIfExists() Removed buggy redundant check in FileUtils.deleteIfExists() Restored current line/current selected lines display on lower left of the IDE. Fixes #3134 Updated cursor.ino New editor on MacOSX: restored CMD+E for finding selected text New editor on MacOSX: CMD+UP/DOWN moves cursor to start or end of sketch. See #3098 New editor on MacOSX: CMD+BACKSPACE deletes current line until cursor position, ALT+BACKSPACE deletes previous word. See #3098 ArduinoIDE is in the default package. Removed Fixes #2969: Fix Uncategorized warning message New editor: ALT+ BACKSPACE deletes next word (OSX only). See #3098 New editor: ALT+ UP/DOWN move current line only if "editor.advanced" (hidden pref) is true. Fixes #3101 New editor: mark occurrences enable when "editor.advanced" (hidden pref) is true. Fixes #3102 ... Conflicts: .gitignore build/build.xml hardware/esp8266com/esp8266/libraries/ESP8266WiFi/keywords.txt hardware/esp8266com/esp8266/libraries/ESP8266WiFi/library.properties hardware/esp8266com/esp8266/libraries/ESP8266WiFi/src/ESP8266WiFi.h libraries/WiFi/README.adoc libraries/WiFi/src/WiFi.cpp libraries/WiFi/src/WiFiClient.cpp libraries/WiFi/src/WiFiClient.h libraries/WiFi/src/WiFiServer.cpp libraries/WiFi/src/WiFiUdp.cpp
This commit is contained in:
@@ -1,45 +1,53 @@
|
||||
package processing.app;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
import cc.arduino.contributions.SignatureVerificationFailedException;
|
||||
import cc.arduino.contributions.libraries.LibrariesIndexer;
|
||||
import cc.arduino.contributions.packages.ContributedTool;
|
||||
import cc.arduino.contributions.packages.ContributionsIndexer;
|
||||
import cc.arduino.files.DeleteFilesOnShutdown;
|
||||
import cc.arduino.packages.DiscoveryManager;
|
||||
import cc.arduino.packages.Uploader;
|
||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import org.apache.commons.logging.impl.LogFactoryImpl;
|
||||
import org.apache.commons.logging.impl.NoOpLog;
|
||||
import processing.app.debug.Compiler;
|
||||
import processing.app.debug.*;
|
||||
import processing.app.helpers.*;
|
||||
import processing.app.helpers.filefilters.OnlyDirs;
|
||||
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.packages.LibraryList;
|
||||
import processing.app.packages.UserLibrary;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.*;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.*;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import org.apache.commons.logging.impl.LogFactoryImpl;
|
||||
import org.apache.commons.logging.impl.NoOpLog;
|
||||
|
||||
import cc.arduino.packages.DiscoveryManager;
|
||||
import cc.arduino.packages.Uploader;
|
||||
|
||||
import processing.app.debug.Compiler;
|
||||
import processing.app.debug.TargetBoard;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.app.debug.TargetPlatform;
|
||||
import processing.app.debug.TargetPlatformException;
|
||||
import processing.app.helpers.BasicUserNotifier;
|
||||
import processing.app.helpers.CommandlineParser;
|
||||
import processing.app.helpers.OSUtils;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
import processing.app.helpers.UserNotifier;
|
||||
import processing.app.helpers.filefilters.OnlyDirs;
|
||||
import processing.app.helpers.filefilters.OnlyFilesWithExtension;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.packages.Library;
|
||||
import processing.app.packages.LibraryList;
|
||||
import static processing.app.I18n._;
|
||||
|
||||
public class BaseNoGui {
|
||||
|
||||
/** Version string to be used for build */
|
||||
public static final int REVISION = 10601;
|
||||
public static final int REVISION = 10605;
|
||||
/** Extended version string displayed on GUI */
|
||||
static String VERSION_NAME = "1.6.1";
|
||||
public static final String VERSION_NAME = "1.6.5";
|
||||
public static final String VERSION_NAME_LONG;
|
||||
|
||||
static {
|
||||
String versionNameLong = VERSION_NAME;
|
||||
File hourlyBuildTxt = new File(getContentFile("lib"), "hourlyBuild.txt");
|
||||
if (hourlyBuildTxt.exists() && hourlyBuildTxt.canRead()) {
|
||||
versionNameLong += " Hourly Build";
|
||||
try {
|
||||
versionNameLong += " " + FileUtils.readFileToString(hourlyBuildTxt).trim();
|
||||
} catch (IOException e) {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
VERSION_NAME_LONG = versionNameLong;
|
||||
}
|
||||
|
||||
static File buildFolder;
|
||||
|
||||
@@ -54,11 +62,12 @@ public class BaseNoGui {
|
||||
static private File toolsFolder;
|
||||
|
||||
// maps #included files to their library folder
|
||||
public static Map<String, Library> importToLibraryTable;
|
||||
public static Map<String, LibraryList> importToLibraryTable;
|
||||
|
||||
// maps library name to their library folder
|
||||
static private LibraryList libraries;
|
||||
|
||||
// XXX: Remove this field
|
||||
static private List<File> librariesFolders;
|
||||
|
||||
static UserNotifier notifier = new BasicUserNotifier();
|
||||
@@ -68,9 +77,11 @@ public class BaseNoGui {
|
||||
static Platform platform;
|
||||
|
||||
static File portableFolder = null;
|
||||
|
||||
static final String portableSketchbookFolder = "sketchbook";
|
||||
|
||||
public static ContributionsIndexer indexer;
|
||||
static LibrariesIndexer librariesIndexer;
|
||||
|
||||
// Returns a File object for the given pathname. If the pathname
|
||||
// is not absolute, it is interpreted relative to the current
|
||||
// directory when starting the IDE (which is not the same as the
|
||||
@@ -139,7 +150,7 @@ public class BaseNoGui {
|
||||
//File folder = new File(getTempFolder(), "build");
|
||||
//if (!folder.exists()) folder.mkdirs();
|
||||
buildFolder = createTempFolder("build");
|
||||
buildFolder.deleteOnExit();
|
||||
DeleteFilesOnShutdown.add(buildFolder);
|
||||
}
|
||||
}
|
||||
return buildFolder;
|
||||
@@ -238,13 +249,6 @@ public class BaseNoGui {
|
||||
return librariesFolders;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an InputStream for a file inside the Processing lib folder.
|
||||
*/
|
||||
static public InputStream getLibStream(String filename) throws IOException {
|
||||
return new FileInputStream(new File(getContentFile("lib"), filename));
|
||||
}
|
||||
|
||||
static public Platform getPlatform() {
|
||||
return platform;
|
||||
}
|
||||
@@ -403,9 +407,8 @@ public class BaseNoGui {
|
||||
}
|
||||
|
||||
static public LibraryList getUserLibs() {
|
||||
if (libraries == null)
|
||||
return new LibraryList();
|
||||
return libraries.filterLibrariesInSubfolder(getSketchbookFolder());
|
||||
LibraryList libs = BaseNoGui.librariesIndexer.getInstalledLibraries();
|
||||
return libs.filterLibrariesInSubfolder(getSketchbookFolder());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,7 +424,7 @@ public class BaseNoGui {
|
||||
return list;
|
||||
}
|
||||
|
||||
static public void init(String[] args) {
|
||||
static public void init(String[] args) throws Exception {
|
||||
getPlatform().init();
|
||||
|
||||
String sketchbookPath = getSketchbookPath();
|
||||
@@ -508,7 +511,7 @@ public class BaseNoGui {
|
||||
// - calls Sketch.build(verbose=false) that calls Sketch.ensureExistence(), set progressListener and calls Compiler.build()
|
||||
// - calls Sketch.upload() (see later...)
|
||||
if (!data.getFolder().exists()) showError(_("No sketch"), _("Can't find the sketch in the specified path"), null);
|
||||
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild());
|
||||
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild(), false);
|
||||
if (suggestedClassName == null) showError(_("Error while verifying"), _("An error occurred while verifying the sketch"), null);
|
||||
showMessage(_("Done compiling"), _("Done compiling"));
|
||||
|
||||
@@ -553,7 +556,7 @@ public class BaseNoGui {
|
||||
// if (!data.getFolder().exists()) showError(...);
|
||||
// String ... = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, verbose);
|
||||
if (!data.getFolder().exists()) showError(_("No sketch"), _("Can't find the sketch in the specified path"), null);
|
||||
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild());
|
||||
String suggestedClassName = Compiler.build(data, tempBuildFolder.getAbsolutePath(), tempBuildFolder, null, parser.isDoVerboseBuild(), false);
|
||||
if (suggestedClassName == null) showError(_("Error while verifying"), _("An error occurred while verifying the sketch"), null);
|
||||
showMessage(_("Done compiling"), _("Done compiling"));
|
||||
} catch (Exception e) {
|
||||
@@ -582,13 +585,77 @@ public class BaseNoGui {
|
||||
Logger.getLogger("javax.jmdns").setLevel(Level.OFF);
|
||||
}
|
||||
|
||||
static public void initPackages() {
|
||||
static public void initPackages() throws Exception {
|
||||
indexer = new ContributionsIndexer(BaseNoGui.getSettingsFolder());
|
||||
File indexFile = indexer.getIndexFile("package_index.json");
|
||||
File defaultPackageJsonFile = new File(getContentFile("dist"), "package_index.json");
|
||||
if (!indexFile.isFile() || (defaultPackageJsonFile.isFile() && defaultPackageJsonFile.lastModified() > indexFile.lastModified())) {
|
||||
FileUtils.copyFile(defaultPackageJsonFile, indexFile);
|
||||
} else if (!indexFile.isFile()) {
|
||||
// Otherwise create an empty packages index
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
out = new FileOutputStream(indexFile);
|
||||
out.write("{ \"packages\" : [ ] }".getBytes());
|
||||
out.close();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
File indexSignatureFile = indexer.getIndexFile("package_index.json.sig");
|
||||
File defaultPackageJsonSignatureFile = new File(getContentFile("dist"), "package_index.json.sig");
|
||||
if (!indexSignatureFile.isFile() || (defaultPackageJsonSignatureFile.isFile() && defaultPackageJsonSignatureFile.lastModified() > indexSignatureFile.lastModified())) {
|
||||
FileUtils.copyFile(defaultPackageJsonSignatureFile, indexSignatureFile);
|
||||
}
|
||||
|
||||
try {
|
||||
indexer.parseIndex();
|
||||
} catch (JsonProcessingException e) {
|
||||
FileUtils.deleteIfExists(indexFile);
|
||||
FileUtils.deleteIfExists(indexSignatureFile);
|
||||
throw e;
|
||||
} catch (SignatureVerificationFailedException e) {
|
||||
FileUtils.deleteIfExists(indexFile);
|
||||
FileUtils.deleteIfExists(indexSignatureFile);
|
||||
throw e;
|
||||
}
|
||||
indexer.syncWithFilesystem(getHardwareFolder());
|
||||
|
||||
packages = new HashMap<String, TargetPackage>();
|
||||
loadHardware(getHardwareFolder());
|
||||
loadHardware(getSketchbookHardwareFolder());
|
||||
if (packages.size() == 0) {
|
||||
System.out.println(_("No valid configured cores found! Exiting..."));
|
||||
System.exit(3);
|
||||
loadContributedHardware(indexer);
|
||||
createToolPreferences(indexer);
|
||||
|
||||
librariesIndexer = new LibrariesIndexer(BaseNoGui.getSettingsFolder());
|
||||
File librariesIndexFile = librariesIndexer.getIndexFile();
|
||||
if (!librariesIndexFile.isFile()) {
|
||||
File defaultLibraryJsonFile = new File(getContentFile("dist"), "library_index.json");
|
||||
if (defaultLibraryJsonFile.isFile()) {
|
||||
FileUtils.copyFile(defaultLibraryJsonFile, librariesIndexFile);
|
||||
} else {
|
||||
FileOutputStream out = null;
|
||||
try {
|
||||
// Otherwise create an empty packages index
|
||||
out = new FileOutputStream(librariesIndexFile);
|
||||
out.write("{ \"libraries\" : [ ] }".getBytes());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
if (out != null) {
|
||||
out.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
try {
|
||||
librariesIndexer.parseIndex();
|
||||
} catch (JsonProcessingException e) {
|
||||
FileUtils.deleteIfExists(librariesIndexFile);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -649,9 +716,9 @@ public class BaseNoGui {
|
||||
File subfolder = new File(folder, target);
|
||||
|
||||
try {
|
||||
packages.put(target, new TargetPackage(target, subfolder));
|
||||
packages.put(target, new LegacyTargetPackage(target, subfolder));
|
||||
} catch (TargetPlatformException e) {
|
||||
System.out.println("WARNING: Error loading hardware folder " + target);
|
||||
System.out.println("WARNING: Error loading hardware folder " + new File(folder, target));
|
||||
System.out.println(" " + e.getMessage());
|
||||
}
|
||||
}
|
||||
@@ -670,6 +737,8 @@ public class BaseNoGui {
|
||||
if (args.length == 0)
|
||||
showError(_("No parameters"), _("No command line parameters found"), null);
|
||||
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(DeleteFilesOnShutdown.INSTANCE));
|
||||
|
||||
initPlatform();
|
||||
|
||||
initPortableFolder();
|
||||
@@ -683,9 +752,10 @@ public class BaseNoGui {
|
||||
examplesFolder = getContentFile("examples");
|
||||
toolsFolder = getContentFile("tools");
|
||||
librariesFolders = new ArrayList<File>();
|
||||
|
||||
// Add IDE libraries folder
|
||||
librariesFolders.add(getContentFile("libraries"));
|
||||
|
||||
// Add library folder for the current selected platform
|
||||
TargetPlatform targetPlatform = getTargetPlatform();
|
||||
if (targetPlatform != null) {
|
||||
String core = getBoardPreferences().get("build.core", "arduino");
|
||||
@@ -694,35 +764,69 @@ public class BaseNoGui {
|
||||
TargetPlatform referencedPlatform = getTargetPlatform(referencedCore, targetPlatform.getId());
|
||||
if (referencedPlatform != null) {
|
||||
File referencedPlatformFolder = referencedPlatform.getFolder();
|
||||
librariesFolders.add(new File(referencedPlatformFolder, "libraries"));
|
||||
// Add libraries folder for the referenced platform
|
||||
File folder = new File(referencedPlatformFolder, "libraries");
|
||||
librariesFolders.add(folder);
|
||||
}
|
||||
}
|
||||
File platformFolder = targetPlatform.getFolder();
|
||||
librariesFolders.add(new File(platformFolder, "libraries"));
|
||||
librariesFolders.add(getSketchbookLibrariesFolder());
|
||||
// Add libraries folder for the selected platform
|
||||
File folder = new File(platformFolder, "libraries");
|
||||
librariesFolders.add(folder);
|
||||
}
|
||||
|
||||
// Add libraries folder for the sketchbook
|
||||
librariesFolders.add(getSketchbookLibrariesFolder());
|
||||
|
||||
// Scan for libraries in each library folder.
|
||||
// Libraries located in the latest folders on the list can override
|
||||
// other libraries with the same name.
|
||||
try {
|
||||
scanAndUpdateLibraries(librariesFolders);
|
||||
} catch (IOException e) {
|
||||
showWarning(_("Error"), _("Error loading libraries"), e);
|
||||
}
|
||||
BaseNoGui.librariesIndexer.setSketchbookLibrariesFolder(getSketchbookLibrariesFolder());
|
||||
BaseNoGui.librariesIndexer.setLibrariesFolders(librariesFolders);
|
||||
BaseNoGui.librariesIndexer.rescanLibraries();
|
||||
|
||||
populateImportToLibraryTable();
|
||||
}
|
||||
|
||||
static protected void loadContributedHardware(ContributionsIndexer indexer) throws TargetPlatformException {
|
||||
for (TargetPackage pack : indexer.createTargetPackages()) {
|
||||
packages.put(pack.getId(), pack);
|
||||
}
|
||||
}
|
||||
|
||||
static private void createToolPreferences(ContributionsIndexer indexer) {
|
||||
// Remove previous runtime preferences
|
||||
final String prefix = "runtime.tools.";
|
||||
PreferencesData.removeAllKeysWithPrefix(prefix);
|
||||
|
||||
for (ContributedTool tool : indexer.getInstalledTools()) {
|
||||
File installedFolder = tool.getDownloadableContribution().getInstalledFolder();
|
||||
if (installedFolder != null) {
|
||||
PreferencesData.set(prefix + tool.getName() + ".path", installedFolder.getAbsolutePath());
|
||||
PreferencesData.set(prefix + tool.getName() + "-" + tool.getVersion() + ".path", installedFolder.getAbsolutePath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public void populateImportToLibraryTable() {
|
||||
// Populate importToLibraryTable
|
||||
importToLibraryTable = new HashMap<String, Library>();
|
||||
for (Library lib : getLibraries()) {
|
||||
// Populate importToLibraryTable. Each header filename maps to
|
||||
// a list of libraries. Compiler.java will use only the first
|
||||
// library on each list. The others are used only to advise
|
||||
// user of ambiguously matched and duplicate libraries.
|
||||
importToLibraryTable = new HashMap<String, LibraryList>();
|
||||
for (UserLibrary lib : librariesIndexer.getInstalledLibraries()) {
|
||||
try {
|
||||
String headers[] = headerListFromIncludePath(lib.getSrcFolder());
|
||||
for (String header : headers) {
|
||||
Library old = importToLibraryTable.get(header);
|
||||
if (old != null) {
|
||||
LibraryList list = importToLibraryTable.get(header);
|
||||
if (list == null) {
|
||||
// This is the first library found with this header
|
||||
list = new LibraryList();
|
||||
list.addFirst(lib);
|
||||
importToLibraryTable.put(header, list);
|
||||
} else {
|
||||
UserLibrary old = list.peekFirst();
|
||||
boolean useThisLib = true;
|
||||
// This is the case where 2 libraries have a .h header
|
||||
// with the same name. We must decide which library to
|
||||
// use when a sketch has #include "name.h"
|
||||
@@ -737,61 +841,84 @@ public class BaseNoGui {
|
||||
// for "libName", then for "oldName".
|
||||
//
|
||||
String name = header.substring(0, header.length() - 2); // name without ".h"
|
||||
String oldName = old.getFolder().getName(); // just the library folder name
|
||||
String libName = lib.getFolder().getName(); // just the library folder name
|
||||
String oldName = old.getInstalledFolder().getName(); // just the library folder name
|
||||
String libName = lib.getInstalledFolder().getName(); // just the library folder name
|
||||
//System.out.println("name conflict: " + name);
|
||||
//System.out.println(" old = " + oldName + " -> " + old.getFolder().getPath());
|
||||
//System.out.println(" new = " + libName + " -> " + lib.getFolder().getPath());
|
||||
//System.out.println(" old = " + oldName + " -> " + old.getInstalledFolder().getPath());
|
||||
//System.out.println(" new = " + libName + " -> " + lib.getInstalledFolder().getPath());
|
||||
String name_lc = name.toLowerCase();
|
||||
String oldName_lc = oldName.toLowerCase();
|
||||
String libName_lc = libName.toLowerCase();
|
||||
// always favor a perfect name match
|
||||
if (libName.equals(name)) {
|
||||
} else if (oldName.equals(name)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
// check for "-master" appended (zip file from github)
|
||||
} else if (libName.equals(name+"-master")) {
|
||||
} else if (oldName.equals(name+"-master")) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
// next, favor a match with other stuff appended
|
||||
} else if (libName.startsWith(name)) {
|
||||
} else if (oldName.startsWith(name)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
// otherwise, favor a match with stuff prepended
|
||||
} else if (libName.endsWith(name)) {
|
||||
} else if (oldName.endsWith(name)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
// as a last resort, match if stuff prepended and appended
|
||||
} else if (libName.contains(name)) {
|
||||
} else if (oldName.contains(name)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
// repeat all the above tests, with case insensitive matching
|
||||
} else if (libName_lc.equals(name_lc)) {
|
||||
} else if (oldName_lc.equals(name_lc)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
} else if (libName_lc.equals(name_lc+"-master")) {
|
||||
} else if (oldName_lc.equals(name_lc+"-master")) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
} else if (libName_lc.startsWith(name_lc)) {
|
||||
} else if (oldName_lc.startsWith(name_lc)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
} else if (libName_lc.endsWith(name_lc)) {
|
||||
} else if (oldName_lc.endsWith(name_lc)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
} else if (libName_lc.contains(name_lc)) {
|
||||
} else if (oldName_lc.contains(name_lc)) {
|
||||
continue;
|
||||
useThisLib = false;
|
||||
} else {
|
||||
// none of these tests matched, so just default to "libName".
|
||||
}
|
||||
if (useThisLib) {
|
||||
list.addFirst(lib);
|
||||
} else {
|
||||
list.addLast(lib);
|
||||
}
|
||||
}
|
||||
importToLibraryTable.put(header, lib);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
showWarning(_("Error"), I18n
|
||||
.format("Unable to list header files in {0}", lib.getSrcFolder()), e);
|
||||
}
|
||||
}
|
||||
// repeat for ALL libraries, to pick up duplicates not visible normally.
|
||||
// any new libraries found here are NEVER used, but they are added to the
|
||||
// end of already-found headers, to allow Compiler to report them if
|
||||
// the sketch tries to use them.
|
||||
for (UserLibrary lib : librariesIndexer.getInstalledLibrariesWithDuplicates()) {
|
||||
try {
|
||||
String headers[] = headerListFromIncludePath(lib.getSrcFolder());
|
||||
for (String header : headers) {
|
||||
LibraryList list = importToLibraryTable.get(header);
|
||||
if (list != null) {
|
||||
if (!(list.hasLibrary(lib))) {
|
||||
list.addLast(lib);
|
||||
//System.out.println(" duplicate lib: " + lib.getInstalledFolder().getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public void initParameters(String args[]) {
|
||||
@@ -926,49 +1053,6 @@ public class BaseNoGui {
|
||||
}
|
||||
}
|
||||
|
||||
static public void scanAndUpdateLibraries(List<File> folders) throws IOException {
|
||||
libraries = scanLibraries(folders);
|
||||
}
|
||||
|
||||
static public LibraryList scanLibraries(List<File> folders) throws IOException {
|
||||
LibraryList res = new LibraryList();
|
||||
for (File folder : folders)
|
||||
res.addOrReplaceAll(scanLibraries(folder));
|
||||
return res;
|
||||
}
|
||||
|
||||
static public LibraryList scanLibraries(File folder) throws IOException {
|
||||
LibraryList res = new LibraryList();
|
||||
|
||||
String list[] = folder.list(new OnlyDirs());
|
||||
// if a bad folder or something like that, this might come back null
|
||||
if (list == null)
|
||||
return res;
|
||||
|
||||
for (String libName : list) {
|
||||
File subfolder = new File(folder, libName);
|
||||
if (!isSanitaryName(libName)) {
|
||||
String mess = I18n.format(_("The library \"{0}\" cannot be used.\n"
|
||||
+ "Library names must contain only basic letters and numbers.\n"
|
||||
+ "(ASCII only and no spaces, and it cannot start with a number)"),
|
||||
libName);
|
||||
showMessage(_("Ignoring bad library name"), mess);
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Library lib = Library.create(subfolder);
|
||||
// (also replace previously found libs with the same name)
|
||||
if (lib != null)
|
||||
res.addOrReplace(lib);
|
||||
} catch (IOException e) {
|
||||
System.out.println(I18n.format(_("Invalid library found in {0}: {1}"),
|
||||
subfolder, e.getMessage()));
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
static public void selectBoard(TargetBoard targetBoard) {
|
||||
TargetPlatform targetPlatform = targetBoard.getContainerPlatform();
|
||||
TargetPackage targetPackage = targetPlatform.getContainerPackage();
|
||||
|
@@ -24,11 +24,11 @@ public class I18n {
|
||||
|
||||
// prompt text stuff
|
||||
|
||||
static String PROMPT_YES;
|
||||
static String PROMPT_NO;
|
||||
static String PROMPT_CANCEL;
|
||||
static String PROMPT_OK;
|
||||
static String PROMPT_BROWSE;
|
||||
public static String PROMPT_YES;
|
||||
public static String PROMPT_NO;
|
||||
public static String PROMPT_CANCEL;
|
||||
public static String PROMPT_OK;
|
||||
public static String PROMPT_BROWSE;
|
||||
|
||||
static protected void init(String language) throws MissingResourceException {
|
||||
String[] languageParts = language.split("_");
|
||||
|
@@ -21,24 +21,19 @@
|
||||
*/
|
||||
|
||||
package processing.app;
|
||||
import static processing.app.I18n._;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import cc.arduino.packages.BoardPort;
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
import processing.app.debug.TargetBoard;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.app.debug.TargetPlatform;
|
||||
import processing.app.legacy.PConstants;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
|
||||
|
||||
/**
|
||||
* Used by Base for platform-specific tweaking, for instance finding the
|
||||
@@ -75,7 +70,7 @@ public class Platform {
|
||||
}
|
||||
|
||||
|
||||
public void init() {
|
||||
public void init() throws IOException {
|
||||
}
|
||||
|
||||
|
||||
@@ -169,6 +164,8 @@ public class Platform {
|
||||
}
|
||||
|
||||
public String resolveDeviceByBoardID(Map<String, TargetPackage> packages, String boardId) {
|
||||
assert packages != null;
|
||||
assert boardId != null;
|
||||
for (TargetPackage targetPackage : packages.values()) {
|
||||
for (TargetPlatform targetPlatform : targetPackage.getPlatforms().values()) {
|
||||
for (TargetBoard board : targetPlatform.getBoards().values()) {
|
||||
@@ -183,33 +180,6 @@ public class Platform {
|
||||
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
public interface CLibrary extends Library {
|
||||
CLibrary INSTANCE = (CLibrary)Native.loadLibrary("c", CLibrary.class);
|
||||
int setenv(String name, String value, int overwrite);
|
||||
String getenv(String name);
|
||||
int unsetenv(String name);
|
||||
int putenv(String string);
|
||||
}
|
||||
|
||||
|
||||
public void setenv(String variable, String value) {
|
||||
CLibrary clib = CLibrary.INSTANCE;
|
||||
clib.setenv(variable, value, 1);
|
||||
}
|
||||
|
||||
|
||||
public String getenv(String variable) {
|
||||
CLibrary clib = CLibrary.INSTANCE;
|
||||
return clib.getenv(variable);
|
||||
}
|
||||
|
||||
|
||||
public int unsetenv(String variable) {
|
||||
CLibrary clib = CLibrary.INSTANCE;
|
||||
return clib.unsetenv(variable);
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return PConstants.platformNames[PConstants.OTHER];
|
||||
}
|
||||
@@ -227,4 +197,39 @@ public class Platform {
|
||||
public List<BoardPort> filterPorts(List<BoardPort> ports, boolean aBoolean) {
|
||||
return new LinkedList<BoardPort>(ports);
|
||||
}
|
||||
|
||||
public void fixPrefsFilePermissions(File prefsFile) throws IOException, InterruptedException {
|
||||
Process process = Runtime.getRuntime().exec(new String[]{"chmod", "600", prefsFile.getAbsolutePath()}, null, null);
|
||||
process.waitFor();
|
||||
}
|
||||
|
||||
public List<File> postInstallScripts(File folder) {
|
||||
List<File> scripts = new LinkedList<File>();
|
||||
scripts.add(new File(folder, "install_script.sh"));
|
||||
scripts.add(new File(folder, "post_install.sh"));
|
||||
return scripts;
|
||||
}
|
||||
|
||||
public String getOsName() {
|
||||
return System.getProperty("os.name");
|
||||
}
|
||||
|
||||
public String getOsArch() {
|
||||
return System.getProperty("os.arch");
|
||||
}
|
||||
|
||||
public void symlink(String something, File somewhere) throws IOException, InterruptedException {
|
||||
Process process = Runtime.getRuntime().exec(new String[]{"ln", "-s", something, somewhere.getAbsolutePath()}, null, somewhere.getParentFile());
|
||||
process.waitFor();
|
||||
}
|
||||
|
||||
public void link(File something, File somewhere) throws IOException, InterruptedException {
|
||||
Process process = Runtime.getRuntime().exec(new String[]{"ln", something.getAbsolutePath(), somewhere.getAbsolutePath()}, null, null);
|
||||
process.waitFor();
|
||||
}
|
||||
|
||||
public void chmod(File file, int mode) throws IOException, InterruptedException {
|
||||
Process process = Runtime.getRuntime().exec(new String[]{"chmod", Integer.toOctalString(mode), file.getAbsolutePath()}, null, null);
|
||||
process.waitFor();
|
||||
}
|
||||
}
|
||||
|
@@ -2,6 +2,7 @@ package processing.app;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
|
||||
import java.awt.*;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@@ -9,8 +10,10 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.PrintWriter;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.MissingResourceException;
|
||||
|
||||
import processing.app.helpers.PreferencesHelper;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.legacy.PConstants;
|
||||
@@ -18,7 +21,7 @@ import processing.app.legacy.PConstants;
|
||||
|
||||
public class PreferencesData {
|
||||
|
||||
static final String PREFS_FILE = "preferences.txt";
|
||||
private static final String PREFS_FILE = "preferences.txt";
|
||||
|
||||
// data model
|
||||
|
||||
@@ -29,18 +32,25 @@ public class PreferencesData {
|
||||
|
||||
|
||||
static public void init(File file) {
|
||||
if (file != null)
|
||||
if (file != null) {
|
||||
preferencesFile = file;
|
||||
else
|
||||
} else {
|
||||
preferencesFile = BaseNoGui.getSettingsFile(PREFS_FILE);
|
||||
}
|
||||
|
||||
try {
|
||||
BaseNoGui.getPlatform().fixPrefsFilePermissions(preferencesFile);
|
||||
} catch (Exception e) {
|
||||
//ignore
|
||||
}
|
||||
|
||||
// start by loading the defaults, in case something
|
||||
// important was deleted from the user prefs
|
||||
try {
|
||||
prefs.load(BaseNoGui.getLibStream("preferences.txt"));
|
||||
prefs.load(new File(BaseNoGui.getContentFile("lib"), PREFS_FILE));
|
||||
} catch (IOException e) {
|
||||
BaseNoGui.showError(null, _("Could not read default settings.\n" +
|
||||
"You'll need to reinstall Arduino."), e);
|
||||
"You'll need to reinstall Arduino."), e);
|
||||
}
|
||||
|
||||
// set some runtime constants (not saved on preferences file)
|
||||
@@ -78,6 +88,10 @@ public class PreferencesData {
|
||||
fixPreferences();
|
||||
}
|
||||
|
||||
public static File getPreferencesFile() {
|
||||
return preferencesFile;
|
||||
}
|
||||
|
||||
private static void fixPreferences() {
|
||||
String baud = get("serial.debug_rate");
|
||||
if ("14400".equals(baud) || "28800".equals(baud)) {
|
||||
@@ -86,41 +100,6 @@ public class PreferencesData {
|
||||
}
|
||||
|
||||
|
||||
static public String[] loadStrings(InputStream input) {
|
||||
try {
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
|
||||
String lines[] = new String[100];
|
||||
int lineCount = 0;
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
if (lineCount == lines.length) {
|
||||
String temp[] = new String[lineCount << 1];
|
||||
System.arraycopy(lines, 0, temp, 0, lineCount);
|
||||
lines = temp;
|
||||
}
|
||||
lines[lineCount++] = line;
|
||||
}
|
||||
reader.close();
|
||||
|
||||
if (lineCount == lines.length) {
|
||||
return lines;
|
||||
}
|
||||
|
||||
// resize array to appropriate amount for these lines
|
||||
String output[] = new String[lineCount];
|
||||
System.arraycopy(lines, 0, output, 0, lineCount);
|
||||
return output;
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
//throw new RuntimeException("Error inside loadStrings()");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
static protected void save() {
|
||||
if (!doSave)
|
||||
return;
|
||||
@@ -131,18 +110,30 @@ public class PreferencesData {
|
||||
if (preferencesFile == null) return;
|
||||
|
||||
// Fix for 0163 to properly use Unicode when writing preferences.txt
|
||||
PrintWriter writer = PApplet.createWriter(preferencesFile);
|
||||
PrintWriter writer = null;
|
||||
try {
|
||||
writer = PApplet.createWriter(preferencesFile);
|
||||
|
||||
String[] keys = prefs.keySet().toArray(new String[0]);
|
||||
Arrays.sort(keys);
|
||||
for (String key: keys) {
|
||||
if (key.startsWith("runtime."))
|
||||
continue;
|
||||
writer.println(key + "=" + prefs.get(key));
|
||||
String[] keys = prefs.keySet().toArray(new String[0]);
|
||||
Arrays.sort(keys);
|
||||
for (String key : keys) {
|
||||
if (key.startsWith("runtime."))
|
||||
continue;
|
||||
writer.println(key + "=" + prefs.get(key));
|
||||
}
|
||||
|
||||
writer.flush();
|
||||
} finally {
|
||||
if (writer != null) {
|
||||
writer.close();
|
||||
}
|
||||
}
|
||||
|
||||
writer.flush();
|
||||
writer.close();
|
||||
try {
|
||||
BaseNoGui.getPlatform().fixPrefsFilePermissions(preferencesFile);
|
||||
} catch (Exception e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -194,6 +185,13 @@ public class PreferencesData {
|
||||
return Integer.parseInt(get(attribute));
|
||||
}
|
||||
|
||||
static public int getInteger(String attribute, int defaultValue) {
|
||||
if (has(attribute)) {
|
||||
return getInteger(attribute);
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
static public void setInteger(String key, int value) {
|
||||
set(key, String.valueOf(value));
|
||||
@@ -205,10 +203,27 @@ public class PreferencesData {
|
||||
return new PreferencesMap(prefs);
|
||||
}
|
||||
|
||||
static public void removeAllKeysWithPrefix(String prefix) {
|
||||
Iterator<String> keys = prefs.keySet().iterator();
|
||||
while (keys.hasNext())
|
||||
if (keys.next().startsWith(prefix))
|
||||
keys.remove();
|
||||
}
|
||||
|
||||
// Decide wether changed preferences will be saved. When value is
|
||||
// false, Preferences.save becomes a no-op.
|
||||
static public void setDoSave(boolean value)
|
||||
{
|
||||
doSave = value;
|
||||
}
|
||||
|
||||
static public Font getFont(String attr) {
|
||||
Font font = PreferencesHelper.getFont(prefs, attr);
|
||||
if (font == null) {
|
||||
String value = defaults.get(attr);
|
||||
prefs.put(attr, value);
|
||||
font = PreferencesHelper.getFont(prefs, attr);
|
||||
}
|
||||
return font;
|
||||
}
|
||||
}
|
||||
|
@@ -88,11 +88,12 @@ public class Serial implements SerialPortEventListener {
|
||||
BaseNoGui.getBoardPreferences().get("serial.disableDTR") == null);
|
||||
}
|
||||
|
||||
public static boolean touchPort(String iname, int irate) throws SerialException {
|
||||
public static boolean touchForCDCReset(String iname) throws SerialException {
|
||||
SerialPort serialPort = new SerialPort(iname);
|
||||
try {
|
||||
serialPort.openPort();
|
||||
serialPort.setParams(irate, 8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||
serialPort.setParams(1200, 8, SerialPort.STOPBITS_1, SerialPort.PARITY_NONE);
|
||||
serialPort.setDTR(false);
|
||||
serialPort.closePort();
|
||||
return true;
|
||||
} catch (SerialPortException e) {
|
||||
|
@@ -25,13 +25,7 @@ package processing.app.debug;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
@@ -45,6 +39,9 @@ import cc.arduino.packages.BoardPort;
|
||||
import cc.arduino.packages.Uploader;
|
||||
import cc.arduino.packages.UploaderFactory;
|
||||
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteStreamHandler;
|
||||
import processing.app.BaseNoGui;
|
||||
import processing.app.I18n;
|
||||
import processing.app.PreferencesData;
|
||||
@@ -52,10 +49,12 @@ import processing.app.SketchCode;
|
||||
import processing.app.SketchData;
|
||||
import processing.app.helpers.*;
|
||||
import processing.app.helpers.filefilters.OnlyDirs;
|
||||
import processing.app.packages.Library;
|
||||
import processing.app.packages.LibraryList;
|
||||
import processing.app.preproc.PdePreprocessor;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.packages.LegacyUserLibrary;
|
||||
import processing.app.packages.UserLibrary;
|
||||
import processing.app.tools.DoubleQuotedArgumentsOnWindowsCommandLine;
|
||||
|
||||
public class Compiler implements MessageConsumer {
|
||||
|
||||
@@ -68,6 +67,7 @@ public class Compiler implements MessageConsumer {
|
||||
private SketchData sketch;
|
||||
private PreferencesMap prefs;
|
||||
private boolean verbose;
|
||||
private boolean saveHex;
|
||||
|
||||
private List<File> objectFiles;
|
||||
|
||||
@@ -84,7 +84,7 @@ public class Compiler implements MessageConsumer {
|
||||
|
||||
private ProgressListener progressListener;
|
||||
|
||||
static public String build(SketchData data, String buildPath, File tempBuildFolder, ProgressListener progListener, boolean verbose) throws RunnerException, PreferencesMapException {
|
||||
static public String build(SketchData data, String buildPath, File tempBuildFolder, ProgressListener progListener, boolean verbose, boolean save) throws RunnerException, PreferencesMapException {
|
||||
if (SketchData.checkSketchFile(data.getPrimaryFile()) == null)
|
||||
BaseNoGui.showError(_("Bad file selected"),
|
||||
_("Bad sketch primary file or bad sketch directory structure"), null);
|
||||
@@ -113,9 +113,16 @@ public class Compiler implements MessageConsumer {
|
||||
|
||||
// compile the program. errors will happen as a RunnerException
|
||||
// that will bubble up to whomever called build().
|
||||
if (compiler.compile(verbose)) {
|
||||
compiler.size(compiler.getBuildPreferences());
|
||||
return primaryClassName;
|
||||
try {
|
||||
if (compiler.compile(verbose, save)) {
|
||||
compiler.size(compiler.getBuildPreferences());
|
||||
return primaryClassName;
|
||||
}
|
||||
} catch (RunnerException e) {
|
||||
// when the compile fails, take this opportunity to show
|
||||
// any helpful info possible before throwing the exception
|
||||
compiler.adviseDuplicateLibraries();
|
||||
throw e;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -183,6 +190,9 @@ public class Compiler implements MessageConsumer {
|
||||
sketch = _sketch;
|
||||
prefs = createBuildPreferences(_buildPath, _primaryClassName);
|
||||
|
||||
// provide access to the source tree
|
||||
prefs.put("build.source.path", _sketch.getFolder().getAbsolutePath());
|
||||
|
||||
// Start with an empty progress listener
|
||||
progressListener = new ProgressListener() {
|
||||
@Override
|
||||
@@ -311,10 +321,10 @@ public class Compiler implements MessageConsumer {
|
||||
if (maxDataSize > 0) {
|
||||
System.out
|
||||
.println(I18n
|
||||
.format(
|
||||
_("Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes."),
|
||||
dataSize, maxDataSize, dataSize * 100 / maxDataSize,
|
||||
maxDataSize - dataSize));
|
||||
.format(
|
||||
_("Global variables use {0} bytes ({2}%%) of dynamic memory, leaving {3} bytes for local variables. Maximum is {1} bytes."),
|
||||
dataSize, maxDataSize, dataSize * 100 / maxDataSize,
|
||||
maxDataSize - dataSize));
|
||||
} else {
|
||||
System.out.println(I18n
|
||||
.format(_("Global variables use {0} bytes of dynamic memory."), dataSize));
|
||||
@@ -341,11 +351,16 @@ public class Compiler implements MessageConsumer {
|
||||
* @return true if successful.
|
||||
* @throws RunnerException Only if there's a problem. Only then.
|
||||
*/
|
||||
public boolean compile(boolean _verbose) throws RunnerException, PreferencesMapException {
|
||||
public boolean compile(boolean _verbose, boolean _save) throws RunnerException, PreferencesMapException {
|
||||
preprocess(prefs.get("build.path"));
|
||||
|
||||
verbose = _verbose || PreferencesData.getBoolean("build.verbose");
|
||||
saveHex = _save;
|
||||
sketchIsCompiled = false;
|
||||
|
||||
// Hook runs at Start of Compilation
|
||||
runActions("hooks.prebuild", prefs);
|
||||
|
||||
objectFiles = new ArrayList<File>();
|
||||
|
||||
// 0. include paths for core + all libraries
|
||||
@@ -354,11 +369,15 @@ public class Compiler implements MessageConsumer {
|
||||
includeFolders.add(prefs.getFile("build.core.path"));
|
||||
if (prefs.getFile("build.variant.path") != null)
|
||||
includeFolders.add(prefs.getFile("build.variant.path"));
|
||||
for (Library lib : importedLibraries) {
|
||||
if (verbose)
|
||||
for (UserLibrary lib : importedLibraries) {
|
||||
if (verbose) {
|
||||
String legacy = "";
|
||||
if (lib instanceof LegacyUserLibrary)
|
||||
legacy = "(legacy)";
|
||||
System.out.println(I18n
|
||||
.format(_("Using library {0} in folder: {1} {2}"), lib.getName(),
|
||||
lib.getFolder(), lib.isLegacy() ? "(legacy)" : ""));
|
||||
lib.getInstalledFolder(), legacy));
|
||||
}
|
||||
includeFolders.add(lib.getSrcFolder());
|
||||
}
|
||||
if (verbose)
|
||||
@@ -370,7 +389,7 @@ public class Compiler implements MessageConsumer {
|
||||
String[] overrides = prefs.get("architecture.override_check").split(",");
|
||||
archs.addAll(Arrays.asList(overrides));
|
||||
}
|
||||
for (Library lib : importedLibraries) {
|
||||
for (UserLibrary lib : importedLibraries) {
|
||||
if (!lib.supportsArchitecture(archs)) {
|
||||
System.err.println(I18n
|
||||
.format(_("WARNING: library {0} claims to run on {1} "
|
||||
@@ -382,26 +401,26 @@ public class Compiler implements MessageConsumer {
|
||||
}
|
||||
|
||||
// 1. compile the sketch (already in the buildPath)
|
||||
progressListener.progress(30);
|
||||
progressListener.progress(20);
|
||||
compileSketch(includeFolders);
|
||||
sketchIsCompiled = true;
|
||||
|
||||
// 2. compile the libraries, outputting .o files to: <buildPath>/<library>/
|
||||
// Doesn't really use configPreferences
|
||||
progressListener.progress(40);
|
||||
progressListener.progress(30);
|
||||
compileLibraries(includeFolders);
|
||||
|
||||
// 3. compile the core, outputting .o files to <buildPath> and then
|
||||
// collecting them into the core.a library file.
|
||||
progressListener.progress(50);
|
||||
progressListener.progress(40);
|
||||
compileCore();
|
||||
|
||||
// 4. link it all together into the .elf file
|
||||
progressListener.progress(60);
|
||||
progressListener.progress(50);
|
||||
compileLink();
|
||||
|
||||
// 5. run objcopy to generate output files
|
||||
progressListener.progress(75);
|
||||
progressListener.progress(60);
|
||||
List<String> objcopyPatterns = new ArrayList<String>();
|
||||
for (String key : prefs.keySet()) {
|
||||
if (key.startsWith("recipe.objcopy.") && key.endsWith(".pattern"))
|
||||
@@ -412,10 +431,39 @@ public class Compiler implements MessageConsumer {
|
||||
runRecipe(recipe);
|
||||
}
|
||||
|
||||
// 7. save the hex file
|
||||
if (saveHex) {
|
||||
progressListener.progress(80);
|
||||
saveHex();
|
||||
}
|
||||
|
||||
progressListener.progress(90);
|
||||
|
||||
// Hook runs at End of Compilation
|
||||
runActions("hooks.postbuild", prefs);
|
||||
adviseDuplicateLibraries();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void adviseDuplicateLibraries() {
|
||||
for (int i=0; i < importedDuplicateHeaders.size(); i++) {
|
||||
System.out.println(I18n.format(_("Multiple libraries were found for \"{0}\""),
|
||||
importedDuplicateHeaders.get(i)));
|
||||
boolean first = true;
|
||||
for (UserLibrary lib : importedDuplicateLibraries.get(i)) {
|
||||
if (first) {
|
||||
System.out.println(I18n.format(_(" Used: {0}"),
|
||||
lib.getInstalledFolder().getPath()));
|
||||
first = false;
|
||||
} else {
|
||||
System.out.println(I18n.format(_(" Not used: {0}"),
|
||||
lib.getInstalledFolder().getPath()));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private PreferencesMap createBuildPreferences(String _buildPath,
|
||||
String _primaryClassName)
|
||||
throws RunnerException {
|
||||
@@ -647,7 +695,6 @@ public class Compiler implements MessageConsumer {
|
||||
command = stringList.toArray(new String[stringList.size()]);
|
||||
if (command.length == 0)
|
||||
return;
|
||||
int result = 0;
|
||||
|
||||
if (verbose) {
|
||||
for (String c : command)
|
||||
@@ -655,30 +702,57 @@ public class Compiler implements MessageConsumer {
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
Process process;
|
||||
DefaultExecutor executor = new DefaultExecutor();
|
||||
executor.setStreamHandler(new ExecuteStreamHandler() {
|
||||
@Override
|
||||
public void setProcessInputStream(OutputStream os) throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessErrorStream(InputStream is) throws IOException {
|
||||
forwardToMessage(is);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessOutputStream(InputStream is) throws IOException {
|
||||
forwardToMessage(is);
|
||||
}
|
||||
|
||||
private void forwardToMessage(InputStream is) throws IOException {
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||
String line;
|
||||
while ((line = reader.readLine()) != null) {
|
||||
message(line + "\n");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws IOException {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
CommandLine commandLine = new DoubleQuotedArgumentsOnWindowsCommandLine(command[0]);
|
||||
for (int i = 1; i < command.length; i++) {
|
||||
commandLine.addArgument(command[i], false);
|
||||
}
|
||||
|
||||
int result;
|
||||
executor.setExitValues(null);
|
||||
try {
|
||||
process = ProcessUtils.exec(command);
|
||||
result = executor.execute(commandLine);
|
||||
} catch (IOException e) {
|
||||
RunnerException re = new RunnerException(e.getMessage());
|
||||
re.hideStackTrace();
|
||||
throw re;
|
||||
}
|
||||
|
||||
MessageSiphon in = new MessageSiphon(process.getInputStream(), this);
|
||||
MessageSiphon err = new MessageSiphon(process.getErrorStream(), this);
|
||||
|
||||
// wait for the process to finish. if interrupted
|
||||
// before waitFor returns, continue waiting
|
||||
boolean compiling = true;
|
||||
while (compiling) {
|
||||
try {
|
||||
in.join();
|
||||
err.join();
|
||||
result = process.waitFor();
|
||||
//System.out.println("result is " + result);
|
||||
compiling = false;
|
||||
} catch (InterruptedException ignored) { }
|
||||
}
|
||||
executor.setExitValues(new int[0]);
|
||||
|
||||
// an error was queued up by message(), barf this back to compile(),
|
||||
// which will barf it back to Editor. if you're having trouble
|
||||
@@ -720,10 +794,10 @@ public class Compiler implements MessageConsumer {
|
||||
s = s.substring(0, i) + s.substring(i + (buildPath + File.separator).length());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// look for error line, which contains file name, line number,
|
||||
// and at least the first line of the error message
|
||||
String errorFormat = "([\\w\\d_]+.\\w+):(\\d+):\\s*error:\\s*(.*)\\s*";
|
||||
String errorFormat = "(.+\\.\\w+):(\\d+)(:\\d+)*:\\s*error:\\s*(.*)\\s*";
|
||||
String[] pieces = PApplet.match(s, errorFormat);
|
||||
|
||||
// if (pieces != null && exception == null) {
|
||||
@@ -732,56 +806,56 @@ public class Compiler implements MessageConsumer {
|
||||
// }
|
||||
|
||||
if (pieces != null) {
|
||||
String error = pieces[3], msg = "";
|
||||
String error = pieces[pieces.length - 1], msg = "";
|
||||
|
||||
if (pieces[3].trim().equals("SPI.h: No such file or directory")) {
|
||||
if (error.trim().equals("SPI.h: No such file or directory")) {
|
||||
error = _("Please import the SPI library from the Sketch > Import Library menu.");
|
||||
msg = _("\nAs of Arduino 0019, the Ethernet library depends on the SPI library." +
|
||||
"\nYou appear to be using it or another library that depends on the SPI library.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("'BYTE' was not declared in this scope")) {
|
||||
if (error.trim().equals("'BYTE' was not declared in this scope")) {
|
||||
error = _("The 'BYTE' keyword is no longer supported.");
|
||||
msg = _("\nAs of Arduino 1.0, the 'BYTE' keyword is no longer supported." +
|
||||
"\nPlease use Serial.write() instead.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("no matching function for call to 'Server::Server(int)'")) {
|
||||
if (error.trim().equals("no matching function for call to 'Server::Server(int)'")) {
|
||||
error = _("The Server class has been renamed EthernetServer.");
|
||||
msg = _("\nAs of Arduino 1.0, the Server class in the Ethernet library " +
|
||||
"has been renamed to EthernetServer.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("no matching function for call to 'Client::Client(byte [4], int)'")) {
|
||||
if (error.trim().equals("no matching function for call to 'Client::Client(byte [4], int)'")) {
|
||||
error = _("The Client class has been renamed EthernetClient.");
|
||||
msg = _("\nAs of Arduino 1.0, the Client class in the Ethernet library " +
|
||||
"has been renamed to EthernetClient.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("'Udp' was not declared in this scope")) {
|
||||
if (error.trim().equals("'Udp' was not declared in this scope")) {
|
||||
error = _("The Udp class has been renamed EthernetUdp.");
|
||||
msg = _("\nAs of Arduino 1.0, the Udp class in the Ethernet library " +
|
||||
"has been renamed to EthernetUdp.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("'class TwoWire' has no member named 'send'")) {
|
||||
if (error.trim().equals("'class TwoWire' has no member named 'send'")) {
|
||||
error = _("Wire.send() has been renamed Wire.write().");
|
||||
msg = _("\nAs of Arduino 1.0, the Wire.send() function was renamed " +
|
||||
"to Wire.write() for consistency with other libraries.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("'class TwoWire' has no member named 'receive'")) {
|
||||
if (error.trim().equals("'class TwoWire' has no member named 'receive'")) {
|
||||
error = _("Wire.receive() has been renamed Wire.read().");
|
||||
msg = _("\nAs of Arduino 1.0, the Wire.receive() function was renamed " +
|
||||
"to Wire.read() for consistency with other libraries.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("'Mouse' was not declared in this scope")) {
|
||||
if (error.trim().equals("'Mouse' was not declared in this scope")) {
|
||||
error = _("'Mouse' only supported on the Arduino Leonardo");
|
||||
//msg = _("\nThe 'Mouse' class is only supported on the Arduino Leonardo.\n\n");
|
||||
}
|
||||
|
||||
if (pieces[3].trim().equals("'Keyboard' was not declared in this scope")) {
|
||||
if (error.trim().equals("'Keyboard' was not declared in this scope")) {
|
||||
error = _("'Keyboard' only supported on the Arduino Leonardo");
|
||||
//msg = _("\nThe 'Keyboard' class is only supported on the Arduino Leonardo.\n\n");
|
||||
}
|
||||
@@ -799,13 +873,15 @@ public class Compiler implements MessageConsumer {
|
||||
SketchCode code = sketch.getCode(e.getCodeIndex());
|
||||
String fileName = (code.isExtension("ino") || code.isExtension("pde")) ? code.getPrettyName() : code.getFileName();
|
||||
int lineNum = e.getCodeLine() + 1;
|
||||
s = fileName + ":" + lineNum + ": error: " + pieces[3] + msg;
|
||||
s = fileName + ":" + lineNum + ": error: " + error + msg;
|
||||
}
|
||||
|
||||
if (e != null) {
|
||||
if (exception == null || exception.getMessage().equals(e.getMessage())) {
|
||||
exception = e;
|
||||
exception.hideStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (exception == null && e != null) {
|
||||
exception = e;
|
||||
exception.hideStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
if (s.contains("undefined reference to `SPIClass::begin()'") &&
|
||||
@@ -831,6 +907,8 @@ public class Compiler implements MessageConsumer {
|
||||
dict.put("source_file", sourceFile.getAbsolutePath());
|
||||
dict.put("object_file", objectFile.getAbsolutePath());
|
||||
|
||||
setupWarningFlags(dict);
|
||||
|
||||
String cmd = prefs.getOrExcept(recipe);
|
||||
try {
|
||||
return StringReplacer.formatAndSplit(cmd, dict, true);
|
||||
@@ -839,6 +917,19 @@ public class Compiler implements MessageConsumer {
|
||||
}
|
||||
}
|
||||
|
||||
private void setupWarningFlags(PreferencesMap dict) {
|
||||
if (dict.containsKey("compiler.warning_level")) {
|
||||
String key = "compiler.warning_flags." + dict.get("compiler.warning_level");
|
||||
dict.put("compiler.warning_flags", dict.get(key));
|
||||
} else {
|
||||
dict.put("compiler.warning_flags", dict.get("compiler.warning_flags.none"));
|
||||
}
|
||||
|
||||
if (dict.get("compiler.warning_flags") == null) {
|
||||
dict.remove("compiler.warning_flags");
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
private void createFolder(File folder) throws RunnerException {
|
||||
@@ -886,21 +977,21 @@ public class Compiler implements MessageConsumer {
|
||||
// 2. compile the libraries, outputting .o files to:
|
||||
// <buildPath>/<library>/
|
||||
void compileLibraries(List<File> includeFolders) throws RunnerException, PreferencesMapException {
|
||||
for (Library lib : importedLibraries) {
|
||||
for (UserLibrary lib : importedLibraries) {
|
||||
compileLibrary(lib, includeFolders);
|
||||
}
|
||||
}
|
||||
|
||||
private void compileLibrary(Library lib, List<File> includeFolders)
|
||||
private void compileLibrary(UserLibrary lib, List<File> includeFolders)
|
||||
throws RunnerException, PreferencesMapException {
|
||||
File libFolder = lib.getSrcFolder();
|
||||
File libBuildFolder = prefs.getFile(("build.path"), lib.getName());
|
||||
|
||||
|
||||
if (lib.useRecursion()) {
|
||||
// libBuildFolder == {build.path}/LibName
|
||||
// libFolder == {lib.path}/src
|
||||
recursiveCompileFilesInFolder(libBuildFolder, libFolder, includeFolders);
|
||||
|
||||
|
||||
} else {
|
||||
// libFolder == {lib.path}/
|
||||
// utilityFolder == {lib.path}/utility
|
||||
@@ -908,11 +999,11 @@ public class Compiler implements MessageConsumer {
|
||||
// utilityBuildFolder == {build.path}/LibName/utility
|
||||
File utilityFolder = new File(libFolder, "utility");
|
||||
File utilityBuildFolder = new File(libBuildFolder, "utility");
|
||||
|
||||
|
||||
includeFolders.add(utilityFolder);
|
||||
compileFilesInFolder(libBuildFolder, libFolder, includeFolders);
|
||||
compileFilesInFolder(utilityBuildFolder, utilityFolder, includeFolders);
|
||||
|
||||
|
||||
// other libraries should not see this library's utility/ folder
|
||||
includeFolders.remove(utilityFolder);
|
||||
}
|
||||
@@ -1031,6 +1122,8 @@ public class Compiler implements MessageConsumer {
|
||||
dict.put("object_files", objectFileList);
|
||||
dict.put("ide_version", "" + BaseNoGui.REVISION);
|
||||
|
||||
setupWarningFlags(dict);
|
||||
|
||||
String[] cmdArray;
|
||||
String cmd = prefs.getOrExcept("recipe.c.combine.pattern");
|
||||
try {
|
||||
@@ -1041,6 +1134,18 @@ public class Compiler implements MessageConsumer {
|
||||
execAsynchronously(cmdArray);
|
||||
}
|
||||
|
||||
void runActions(String recipeClass, PreferencesMap prefs) throws RunnerException, PreferencesMapException {
|
||||
List<String> patterns = new ArrayList<String>();
|
||||
for (String key : prefs.keySet()) {
|
||||
if (key.startsWith("recipe."+recipeClass) && key.endsWith(".pattern"))
|
||||
patterns.add(key);
|
||||
}
|
||||
Collections.sort(patterns);
|
||||
for (String recipe : patterns) {
|
||||
runRecipe(recipe);
|
||||
}
|
||||
}
|
||||
|
||||
void runRecipe(String recipe) throws RunnerException, PreferencesMapException {
|
||||
PreferencesMap dict = new PreferencesMap(prefs);
|
||||
dict.put("ide_version", "" + BaseNoGui.REVISION);
|
||||
@@ -1054,6 +1159,32 @@ public class Compiler implements MessageConsumer {
|
||||
}
|
||||
execAsynchronously(cmdArray);
|
||||
}
|
||||
|
||||
//7. Save the .hex file
|
||||
void saveHex() throws RunnerException {
|
||||
if (!prefs.containsKey("recipe.output.tmp_file") || !prefs.containsKey("recipe.output.save_file")) {
|
||||
System.err.println(_("Warning: This core does not support exporting sketches. Please consider upgrading it or contacting its author"));
|
||||
return;
|
||||
}
|
||||
|
||||
PreferencesMap dict = new PreferencesMap(prefs);
|
||||
dict.put("ide_version", "" + BaseNoGui.REVISION);
|
||||
|
||||
try {
|
||||
String compiledSketch = prefs.getOrExcept("recipe.output.tmp_file");
|
||||
compiledSketch = StringReplacer.replaceFromMapping(compiledSketch, dict);
|
||||
String copyOfCompiledSketch = prefs.getOrExcept("recipe.output.save_file");
|
||||
copyOfCompiledSketch = StringReplacer.replaceFromMapping(copyOfCompiledSketch, dict);
|
||||
|
||||
File compiledSketchFile = new File(prefs.get("build.path"), compiledSketch);
|
||||
File copyOfCompiledSketchFile = new File(sketch.getFolder(), copyOfCompiledSketch);
|
||||
|
||||
FileUtils.copyFile(compiledSketchFile, copyOfCompiledSketchFile);
|
||||
} catch (Exception e) {
|
||||
throw new RunnerException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static String prepareIncludes(List<File> includeFolders) {
|
||||
String res = "";
|
||||
@@ -1120,12 +1251,12 @@ public class Compiler implements MessageConsumer {
|
||||
// 2. run preproc on that code using the sugg class name
|
||||
// to create a single .java file and write to buildpath
|
||||
|
||||
FileOutputStream outputStream = null;
|
||||
try {
|
||||
// Output file
|
||||
File streamFile = new File(buildPath, sketch.getName() + ".cpp");
|
||||
FileOutputStream outputStream = new FileOutputStream(streamFile);
|
||||
outputStream = new FileOutputStream(streamFile);
|
||||
preprocessor.write(outputStream);
|
||||
outputStream.close();
|
||||
} catch (FileNotFoundException fnfe) {
|
||||
fnfe.printStackTrace();
|
||||
String msg = _("Build folder disappeared or could not be written");
|
||||
@@ -1140,15 +1271,32 @@ public class Compiler implements MessageConsumer {
|
||||
System.err.println(I18n.format(_("Uncaught exception type: {0}"), ex.getClass()));
|
||||
ex.printStackTrace();
|
||||
throw new RunnerException(ex.toString());
|
||||
} finally {
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// grab the imports from the code just preproc'd
|
||||
|
||||
importedLibraries = new LibraryList();
|
||||
importedDuplicateHeaders = new ArrayList<String>();
|
||||
importedDuplicateLibraries = new ArrayList<LibraryList>();
|
||||
for (String item : preprocessor.getExtraImports()) {
|
||||
Library lib = BaseNoGui.importToLibraryTable.get(item);
|
||||
if (lib != null && !importedLibraries.contains(lib)) {
|
||||
importedLibraries.add(lib);
|
||||
LibraryList list = BaseNoGui.importToLibraryTable.get(item);
|
||||
if (list != null) {
|
||||
UserLibrary lib = list.peekFirst();
|
||||
if (lib != null && !importedLibraries.contains(lib)) {
|
||||
importedLibraries.add(lib);
|
||||
if (list.size() > 1) {
|
||||
importedDuplicateHeaders.add(item);
|
||||
importedDuplicateLibraries.add(list);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1180,6 +1328,8 @@ public class Compiler implements MessageConsumer {
|
||||
* List of library folders.
|
||||
*/
|
||||
private LibraryList importedLibraries;
|
||||
private List<String> importedDuplicateHeaders;
|
||||
private List<LibraryList> importedDuplicateLibraries;
|
||||
|
||||
/**
|
||||
* Map an error from a set of processed .java files back to its location
|
||||
|
113
arduino-core/src/processing/app/debug/LegacyTargetBoard.java
Normal file
113
arduino-core/src/processing/app/debug/LegacyTargetBoard.java
Normal file
@@ -0,0 +1,113 @@
|
||||
/*
|
||||
TargetPackage - Represents a hardware package
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2014 Cristian Maglie
|
||||
|
||||
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.debug;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
import static processing.app.I18n.format;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
public class LegacyTargetBoard implements TargetBoard {
|
||||
|
||||
private String id;
|
||||
private PreferencesMap prefs;
|
||||
private Map<String, PreferencesMap> menuOptions = new LinkedHashMap<String, PreferencesMap>();
|
||||
private TargetPlatform containerPlatform;
|
||||
|
||||
/**
|
||||
* Create a TargetBoard based on preferences passed as argument.
|
||||
*
|
||||
* @param _prefs
|
||||
* @return
|
||||
*/
|
||||
public LegacyTargetBoard(String _id, PreferencesMap _prefs,
|
||||
TargetPlatform parent) {
|
||||
containerPlatform = parent;
|
||||
id = _id;
|
||||
prefs = new PreferencesMap(_prefs);
|
||||
|
||||
// Setup sub-menus
|
||||
PreferencesMap menus = prefs.firstLevelMap().get("menu");
|
||||
if (menus != null)
|
||||
menuOptions = menus.firstLevelMap();
|
||||
|
||||
// Auto generate build.board if not set
|
||||
if (!prefs.containsKey("build.board")) {
|
||||
String board = containerPlatform.getId() + "_" + id;
|
||||
board = board.toUpperCase();
|
||||
prefs.put("build.board", board);
|
||||
System.out
|
||||
.println(format(_("Board {0}:{1}:{2} doesn''t define a ''build.board'' preference. Auto-set to: {3}"),
|
||||
containerPlatform.getContainerPackage().getId(),
|
||||
containerPlatform.getId(), id, board));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return prefs.get("name");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getPreferences() {
|
||||
return prefs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasMenu(String menuId) {
|
||||
return menuOptions.containsKey(menuId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getMenuLabels(String menuId) {
|
||||
return menuOptions.get(menuId).topLevelMap();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMenuLabel(String menuId, String selectionId) {
|
||||
return getMenuLabels(menuId).get(selectionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getMenuIds() {
|
||||
return menuOptions.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getMenuPreferences(String menuId, String selectionId) {
|
||||
return menuOptions.get(menuId).subTree(selectionId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetPlatform getContainerPlatform() {
|
||||
return containerPlatform;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
TargetPackage - Represents a hardware package
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2011 Cristian Maglie
|
||||
|
||||
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.debug;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
import static processing.app.helpers.filefilters.OnlyDirs.ONLY_DIRS;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import processing.app.I18n;
|
||||
|
||||
public class LegacyTargetPackage implements TargetPackage {
|
||||
|
||||
private String id;
|
||||
private Map<String, TargetPlatform> platforms;
|
||||
|
||||
public LegacyTargetPackage(String _id, File _folder) throws TargetPlatformException {
|
||||
id = _id;
|
||||
platforms = new LinkedHashMap<String, TargetPlatform>();
|
||||
|
||||
File[] folders = _folder.listFiles(ONLY_DIRS);
|
||||
if (folders == null)
|
||||
return;
|
||||
|
||||
for (File subFolder : folders) {
|
||||
if (!subFolder.exists() || !subFolder.canRead())
|
||||
continue;
|
||||
String arch = subFolder.getName();
|
||||
try {
|
||||
TargetPlatform platform = new LegacyTargetPlatform(arch, subFolder, this);
|
||||
platforms.put(arch, platform);
|
||||
} catch (TargetPlatformException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (platforms.size() == 0) {
|
||||
throw new TargetPlatformException(I18n
|
||||
.format(_("No valid hardware definitions found in folder {0}."),
|
||||
_folder.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TargetPlatform> getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<TargetPlatform> platforms() {
|
||||
return platforms.values();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetPlatform get(String platform) {
|
||||
return platforms.get(platform);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasPlatform(TargetPlatform platform) {
|
||||
return platforms.containsKey(platform.getId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
}
|
241
arduino-core/src/processing/app/debug/LegacyTargetPlatform.java
Normal file
241
arduino-core/src/processing/app/debug/LegacyTargetPlatform.java
Normal file
@@ -0,0 +1,241 @@
|
||||
/*
|
||||
TargetPlatform - Represents a hardware platform
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2009-2014 Arduino
|
||||
|
||||
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.debug;
|
||||
|
||||
import processing.app.BaseNoGui;
|
||||
import processing.app.I18n;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
import static processing.app.I18n.format;
|
||||
|
||||
public class LegacyTargetPlatform implements TargetPlatform {
|
||||
|
||||
private String id;
|
||||
private File folder;
|
||||
|
||||
private TargetPackage containerPackage;
|
||||
protected PreferencesMap preferences = new PreferencesMap();
|
||||
|
||||
private Map<String, TargetBoard> boards = new LinkedHashMap<String, TargetBoard>();
|
||||
private TargetBoard defaultBoard;
|
||||
|
||||
/**
|
||||
* Contains preferences for every defined programmer
|
||||
*/
|
||||
private Map<String, PreferencesMap> programmers = new LinkedHashMap<String, PreferencesMap>();
|
||||
|
||||
/**
|
||||
* Contains labels for top level menus
|
||||
*/
|
||||
private PreferencesMap customMenus = new PreferencesMap();
|
||||
|
||||
public LegacyTargetPlatform(String _name, File _folder, TargetPackage parent)
|
||||
throws TargetPlatformException {
|
||||
|
||||
id = _name;
|
||||
folder = _folder;
|
||||
containerPackage = parent;
|
||||
|
||||
// If there is no boards.txt, this is not a valid 1.5 hardware folder
|
||||
File boardsFile = new File(folder, "boards.txt");
|
||||
if (!boardsFile.exists() || !boardsFile.canRead())
|
||||
throw new TargetPlatformException(
|
||||
format(_("Could not find boards.txt in {0}. Is it pre-1.5?"),
|
||||
folder.getAbsolutePath()));
|
||||
|
||||
// Load boards
|
||||
try {
|
||||
Map<String, PreferencesMap> boardsPreferences = new PreferencesMap(
|
||||
boardsFile).firstLevelMap();
|
||||
|
||||
// Create custom menus for this platform
|
||||
PreferencesMap menus = boardsPreferences.get("menu");
|
||||
if (menus != null)
|
||||
customMenus = menus.topLevelMap();
|
||||
boardsPreferences.remove("menu");
|
||||
|
||||
// Create boards
|
||||
Set<String> boardIds = boardsPreferences.keySet();
|
||||
for (String boardId : boardIds) {
|
||||
PreferencesMap preferences = boardsPreferences.get(boardId);
|
||||
TargetBoard board = new LegacyTargetBoard(boardId, preferences, this);
|
||||
boards.put(boardId, board);
|
||||
|
||||
// Pick the first board as default
|
||||
if (defaultBoard == null)
|
||||
defaultBoard = board;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(format(_("Error loading {0}"),
|
||||
boardsFile.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
File platformsFile = new File(folder, "platform.txt");
|
||||
try {
|
||||
if (platformsFile.exists() && platformsFile.canRead()) {
|
||||
preferences.load(platformsFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(
|
||||
format(_("Error loading {0}"), platformsFile.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
// Allow overriding values in platform.txt. This allows changing
|
||||
// platform.txt (e.g. to use a system-wide toolchain), without
|
||||
// having to modify platform.txt (which, when running from git,
|
||||
// prevents files being marked as changed).
|
||||
File localPlatformsFile = new File(folder, "platform.local.txt");
|
||||
try {
|
||||
if (localPlatformsFile.exists() && localPlatformsFile.canRead()) {
|
||||
preferences.load(localPlatformsFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(
|
||||
format(_("Error loading {0}"), localPlatformsFile.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
if (!preferences.containsKey("rewriting") || !"disabled".equals(preferences.get("rewriting"))) {
|
||||
try {
|
||||
rewriteKeysOfOldPlatformsTxtAndWarnAboutIt();
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(e);
|
||||
}
|
||||
}
|
||||
|
||||
File progFile = new File(folder, "programmers.txt");
|
||||
try {
|
||||
if (progFile.exists() && progFile.canRead()) {
|
||||
PreferencesMap prefs = new PreferencesMap();
|
||||
prefs.load(progFile);
|
||||
programmers = prefs.firstLevelMap();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(format(_("Error loading {0}"),
|
||||
progFile.getAbsolutePath()), e);
|
||||
}
|
||||
}
|
||||
|
||||
private void rewriteKeysOfOldPlatformsTxtAndWarnAboutIt() throws IOException {
|
||||
File platformRewrite = new File(BaseNoGui.getHardwareFolder(), "platform.keys.rewrite.txt");
|
||||
PreferencesMap platformRewriteProps = new PreferencesMap(platformRewrite);
|
||||
|
||||
PreferencesMap oldProps = platformRewriteProps.subTree("old");
|
||||
PreferencesMap newProps = platformRewriteProps.subTree("new");
|
||||
|
||||
String platformName = preferences.get("name");
|
||||
if (platformName == null) {
|
||||
platformName = folder.getAbsolutePath();
|
||||
}
|
||||
|
||||
for (Map.Entry<String, String> entry : oldProps.entrySet()) {
|
||||
String preferencesKey = entry.getKey().substring(entry.getKey().indexOf(".") + 1);
|
||||
if (preferences.containsKey(preferencesKey) && entry.getValue().equals(preferences.get(preferencesKey))) {
|
||||
System.err.println(I18n.format(_("Warning: platform.txt from core '{0}' contains deprecated {1}, automatically converted to {2}. Consider upgrading this core."), platformName, preferencesKey + "=" + entry.getValue(), preferencesKey + "=" + newProps.get(entry.getKey())));
|
||||
preferences.put(preferencesKey, newProps.get(entry.getKey()));
|
||||
}
|
||||
}
|
||||
|
||||
PreferencesMap addedProps = platformRewriteProps.subTree("added");
|
||||
for (Map.Entry<String, String> entry : addedProps.entrySet()) {
|
||||
String keyToAdd = entry.getKey();
|
||||
String[] keyToAddParts = keyToAdd.split("\\.");
|
||||
String keyToAddFirstLevel = keyToAddParts[0];
|
||||
String keyToAddSecondLevel = keyToAddParts[0] + "." + keyToAddParts[1];
|
||||
if (!preferences.subTree(keyToAddFirstLevel).isEmpty() && !preferences.subTree(keyToAddSecondLevel).isEmpty() && !preferences.containsKey(keyToAdd)) {
|
||||
System.err.println(I18n.format(_("Warning: platform.txt from core '{0}' misses property {1}, automatically set to {2}. Consider upgrading this core."), platformName, keyToAdd, entry.getValue()));
|
||||
preferences.put(keyToAdd, entry.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public File getFolder() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, TargetBoard> getBoards() {
|
||||
return boards;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getCustomMenus() {
|
||||
return customMenus;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<String> getCustomMenuIds() {
|
||||
return customMenus.keySet();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, PreferencesMap> getProgrammers() {
|
||||
return programmers;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getProgrammer(String programmer) {
|
||||
return getProgrammers().get(programmer);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getTool(String tool) {
|
||||
return getPreferences().subTree("tools").subTree(tool);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PreferencesMap getPreferences() {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetBoard getBoard(String boardId) {
|
||||
if (boards.containsKey(boardId)) {
|
||||
return boards.get(boardId);
|
||||
}
|
||||
return defaultBoard;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TargetPackage getContainerPackage() {
|
||||
return containerPackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String res = "TargetPlatform: name=" + id + " boards={\n";
|
||||
for (String boardId : boards.keySet())
|
||||
res += " " + boardId + " = " + boards.get(boardId) + "\n";
|
||||
return res + "}";
|
||||
}
|
||||
}
|
@@ -1,76 +1,51 @@
|
||||
/*
|
||||
TargetBoard - Represents a hardware board
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2014 Cristian Maglie
|
||||
|
||||
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.debug;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
import static processing.app.I18n.format;
|
||||
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
public class TargetBoard {
|
||||
|
||||
private String id;
|
||||
private PreferencesMap prefs;
|
||||
private Map<String, PreferencesMap> menuOptions = new LinkedHashMap<String, PreferencesMap>();
|
||||
private TargetPlatform containerPlatform;
|
||||
|
||||
/**
|
||||
* Create a TargetBoard based on preferences passed as argument.
|
||||
*
|
||||
* @param _prefs
|
||||
* @return
|
||||
*/
|
||||
public TargetBoard(String _id, PreferencesMap _prefs, TargetPlatform parent) {
|
||||
containerPlatform = parent;
|
||||
id = _id;
|
||||
prefs = new PreferencesMap(_prefs);
|
||||
|
||||
// Setup sub-menus
|
||||
PreferencesMap menus = prefs.firstLevelMap().get("menu");
|
||||
if (menus != null)
|
||||
menuOptions = menus.firstLevelMap();
|
||||
|
||||
// Auto generate build.board if not set
|
||||
if (!prefs.containsKey("build.board")) {
|
||||
String board = containerPlatform.getId() + "_" + id;
|
||||
board = board.toUpperCase();
|
||||
prefs.put("build.board", board);
|
||||
System.out
|
||||
.println(format(
|
||||
_("Board {0}:{1}:{2} doesn''t define a ''build.board'' preference. Auto-set to: {3}"),
|
||||
containerPlatform.getContainerPackage().getId(),
|
||||
containerPlatform.getId(), id, board));
|
||||
}
|
||||
}
|
||||
public interface TargetBoard {
|
||||
|
||||
/**
|
||||
* Get the name of the board.
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getName() {
|
||||
return prefs.get("name");
|
||||
}
|
||||
public String getName();
|
||||
|
||||
/**
|
||||
* Get the identifier of the board
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
public String getId();
|
||||
|
||||
/**
|
||||
* Get the full preferences map of the board with a given identifier
|
||||
* Get the full preferences map of the board
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public PreferencesMap getPreferences() {
|
||||
return prefs;
|
||||
}
|
||||
public PreferencesMap getPreferences();
|
||||
|
||||
/**
|
||||
* Check if the board has a sub menu.
|
||||
@@ -79,9 +54,7 @@ public class TargetBoard {
|
||||
* The menu ID to check
|
||||
* @return
|
||||
*/
|
||||
public boolean hasMenu(String menuId) {
|
||||
return menuOptions.containsKey(menuId);
|
||||
}
|
||||
public boolean hasMenu(String menuId);
|
||||
|
||||
/**
|
||||
* Returns the options available on a specific menu
|
||||
@@ -90,9 +63,7 @@ public class TargetBoard {
|
||||
* The menu ID
|
||||
* @return
|
||||
*/
|
||||
public PreferencesMap getMenuLabels(String menuId) {
|
||||
return menuOptions.get(menuId).topLevelMap();
|
||||
}
|
||||
public PreferencesMap getMenuLabels(String menuId);
|
||||
|
||||
/**
|
||||
* Returns the label of the specified option in the specified menu
|
||||
@@ -103,13 +74,9 @@ public class TargetBoard {
|
||||
* The option ID
|
||||
* @return
|
||||
*/
|
||||
public String getMenuLabel(String menuId, String selectionId) {
|
||||
return getMenuLabels(menuId).get(selectionId);
|
||||
}
|
||||
public String getMenuLabel(String menuId, String selectionId);
|
||||
|
||||
public Set<String> getMenuIds() {
|
||||
return menuOptions.keySet();
|
||||
}
|
||||
public Set<String> getMenuIds();
|
||||
|
||||
/**
|
||||
* Returns the configuration parameters to override (as a PreferenceMap) when
|
||||
@@ -121,12 +88,8 @@ public class TargetBoard {
|
||||
* The option ID
|
||||
* @return
|
||||
*/
|
||||
public PreferencesMap getMenuPreferences(String menuId, String selectionId) {
|
||||
return menuOptions.get(menuId).subTree(selectionId);
|
||||
}
|
||||
public PreferencesMap getMenuPreferences(String menuId, String selectionId);
|
||||
|
||||
public TargetPlatform getContainerPlatform() {
|
||||
return containerPlatform;
|
||||
}
|
||||
public TargetPlatform getContainerPlatform();
|
||||
|
||||
}
|
||||
|
@@ -1,9 +1,8 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
TargetPackage - Represents a hardware package
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2011 Cristian Maglie
|
||||
Copyright (c) 2014 Cristian Maglie
|
||||
|
||||
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
|
||||
@@ -21,61 +20,18 @@
|
||||
*/
|
||||
package processing.app.debug;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import processing.app.I18n;
|
||||
import processing.app.helpers.filefilters.OnlyDirs;
|
||||
public interface TargetPackage {
|
||||
|
||||
public class TargetPackage {
|
||||
String getId();
|
||||
|
||||
private String id;
|
||||
Map<String, TargetPlatform> getPlatforms();
|
||||
|
||||
Map<String, TargetPlatform> platforms = new LinkedHashMap<String, TargetPlatform>();
|
||||
Collection<TargetPlatform> platforms();
|
||||
|
||||
public TargetPackage(String _id, File _folder) throws TargetPlatformException {
|
||||
id = _id;
|
||||
TargetPlatform get(String platform);
|
||||
|
||||
File[] folders = _folder.listFiles(new OnlyDirs());
|
||||
if (folders == null)
|
||||
return;
|
||||
|
||||
for (File subFolder : folders) {
|
||||
if (!subFolder.exists() || !subFolder.canRead())
|
||||
continue;
|
||||
String arch = subFolder.getName();
|
||||
try {
|
||||
TargetPlatform platform = new TargetPlatform(arch, subFolder, this);
|
||||
platforms.put(arch, platform);
|
||||
} catch (TargetPlatformException e) {
|
||||
System.out.println(e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
if (platforms.size() == 0) {
|
||||
throw new TargetPlatformException(I18n
|
||||
.format(_("No valid hardware definitions found in folder {0}."),
|
||||
_folder.getName()));
|
||||
}
|
||||
}
|
||||
|
||||
public Map<String, TargetPlatform> getPlatforms() {
|
||||
return platforms;
|
||||
}
|
||||
|
||||
public Collection<TargetPlatform> platforms() {
|
||||
return platforms.values();
|
||||
}
|
||||
|
||||
public TargetPlatform get(String platform) {
|
||||
return platforms.get(platform);
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
boolean hasPlatform(TargetPlatform platform);
|
||||
}
|
||||
|
@@ -1,9 +1,8 @@
|
||||
/* -*- mode: jde; c-basic-offset: 2; indent-tabs-mode: nil -*- */
|
||||
/*
|
||||
TargetPlatform - Represents a hardware platform
|
||||
Part of the Arduino project - http://www.arduino.cc/
|
||||
|
||||
Copyright (c) 2009 David A. Mellis
|
||||
Copyright (c) 2014 Arduino
|
||||
|
||||
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
|
||||
@@ -21,174 +20,78 @@
|
||||
*/
|
||||
package processing.app.debug;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
import static processing.app.I18n.format;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
public class TargetPlatform {
|
||||
public interface TargetPlatform {
|
||||
|
||||
private String id;
|
||||
private File folder;
|
||||
private TargetPackage containerPackage;
|
||||
public String getId();
|
||||
|
||||
public File getFolder();
|
||||
|
||||
/**
|
||||
* Contains preferences for every defined board
|
||||
* Get TargetBoards under this TargetPlatform into a Map that maps the board
|
||||
* id with the corresponding TargetBoard
|
||||
*
|
||||
* @return a Map<String, TargetBoard>
|
||||
*/
|
||||
private Map<String, TargetBoard> boards = new LinkedHashMap<String, TargetBoard>();
|
||||
private TargetBoard defaultBoard;
|
||||
public Map<String, TargetBoard> getBoards();
|
||||
|
||||
public PreferencesMap getCustomMenus();
|
||||
|
||||
/**
|
||||
* Contains preferences for every defined programmer
|
||||
* Return ids for top level menus
|
||||
*
|
||||
* @return a Set<String> with the ids of the top level custom menus
|
||||
*/
|
||||
private Map<String, PreferencesMap> programmers = new LinkedHashMap<String, PreferencesMap>();
|
||||
public Set<String> getCustomMenuIds();
|
||||
|
||||
/**
|
||||
* Contains preferences for platform
|
||||
* Get preferences for all programmers
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
private PreferencesMap preferences = new PreferencesMap();
|
||||
public Map<String, PreferencesMap> getProgrammers();
|
||||
|
||||
/**
|
||||
* Contains labels for top level menus
|
||||
* Get preferences for a specific programmer
|
||||
*
|
||||
* @param programmer
|
||||
* @return
|
||||
*/
|
||||
private PreferencesMap customMenus = new PreferencesMap();
|
||||
public PreferencesMap getProgrammer(String programmer);
|
||||
|
||||
public TargetPlatform(String _name, File _folder, TargetPackage parent)
|
||||
throws TargetPlatformException {
|
||||
/**
|
||||
* Get preferences for a specific tool
|
||||
*
|
||||
* @param tool
|
||||
* @return
|
||||
*/
|
||||
public PreferencesMap getTool(String tool);
|
||||
|
||||
id = _name;
|
||||
folder = _folder;
|
||||
containerPackage = parent;
|
||||
/**
|
||||
* Return TargetPlatform preferences
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public PreferencesMap getPreferences();
|
||||
|
||||
// If there is no boards.txt, this is not a valid 1.5 hardware folder
|
||||
File boardsFile = new File(folder, "boards.txt");
|
||||
if (!boardsFile.exists() || !boardsFile.canRead())
|
||||
throw new TargetPlatformException(
|
||||
format(_("Could not find boards.txt in {0}. Is it pre-1.5?"),
|
||||
folder.getAbsolutePath()));
|
||||
/**
|
||||
* Get a target board
|
||||
*
|
||||
* @param boardId
|
||||
* @return
|
||||
*/
|
||||
public TargetBoard getBoard(String boardId);
|
||||
|
||||
// Load boards
|
||||
try {
|
||||
Map<String, PreferencesMap> boardsPreferences = new PreferencesMap(
|
||||
boardsFile).firstLevelMap();
|
||||
/**
|
||||
* Get the TargetPackage that contains this TargetPlatform
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
public TargetPackage getContainerPackage();
|
||||
|
||||
// Create custom menus for this platform
|
||||
PreferencesMap menus = boardsPreferences.get("menu");
|
||||
if (menus != null)
|
||||
customMenus = menus.topLevelMap();
|
||||
boardsPreferences.remove("menu");
|
||||
|
||||
// Create boards
|
||||
Set<String> boardIds = boardsPreferences.keySet();
|
||||
for (String boardId : boardIds) {
|
||||
PreferencesMap preferences = boardsPreferences.get(boardId);
|
||||
TargetBoard board = new TargetBoard(boardId, preferences, this);
|
||||
boards.put(boardId, board);
|
||||
|
||||
// Pick the first board as default
|
||||
if (defaultBoard == null)
|
||||
defaultBoard = board;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(format(_("Error loading {0}"),
|
||||
boardsFile.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
File platformsFile = new File(folder, "platform.txt");
|
||||
try {
|
||||
if (platformsFile.exists() && platformsFile.canRead()) {
|
||||
preferences.load(platformsFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(
|
||||
format(_("Error loading {0}"), platformsFile.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
// Allow overriding values in platform.txt. This allows changing
|
||||
// platform.txt (e.g. to use a system-wide toolchain), without
|
||||
// having to modify platform.txt (which, when running from git,
|
||||
// prevents files being marked as changed).
|
||||
File localPlatformsFile = new File(folder, "platform.local.txt");
|
||||
try {
|
||||
if (localPlatformsFile.exists() && localPlatformsFile.canRead()) {
|
||||
preferences.load(localPlatformsFile);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(
|
||||
format(_("Error loading {0}"), localPlatformsFile.getAbsolutePath()), e);
|
||||
}
|
||||
|
||||
File progFile = new File(folder, "programmers.txt");
|
||||
try {
|
||||
if (progFile.exists() && progFile.canRead()) {
|
||||
PreferencesMap prefs = new PreferencesMap();
|
||||
prefs.load(progFile);
|
||||
programmers = prefs.firstLevelMap();
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new TargetPlatformException(format(_("Error loading {0}"), progFile
|
||||
.getAbsolutePath()), e);
|
||||
}
|
||||
}
|
||||
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public File getFolder() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
public Map<String, TargetBoard> getBoards() {
|
||||
return boards;
|
||||
}
|
||||
|
||||
public PreferencesMap getCustomMenus() {
|
||||
return customMenus;
|
||||
}
|
||||
|
||||
public Set<String> getCustomMenuIds() {
|
||||
return customMenus.keySet();
|
||||
}
|
||||
|
||||
public Map<String, PreferencesMap> getProgrammers() {
|
||||
return programmers;
|
||||
}
|
||||
|
||||
public PreferencesMap getProgrammer(String programmer) {
|
||||
return getProgrammers().get(programmer);
|
||||
}
|
||||
|
||||
public PreferencesMap getTool(String tool) {
|
||||
return getPreferences().subTree("tools").subTree(tool);
|
||||
}
|
||||
|
||||
public PreferencesMap getPreferences() {
|
||||
return preferences;
|
||||
}
|
||||
|
||||
public TargetBoard getBoard(String boardId) {
|
||||
if (boards.containsKey(boardId)) {
|
||||
return boards.get(boardId);
|
||||
}
|
||||
return defaultBoard;
|
||||
}
|
||||
|
||||
public TargetPackage getContainerPackage() {
|
||||
return containerPackage;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String res = "TargetPlatform: name=" + id + " boards={\n";
|
||||
for (String boardId : boards.keySet())
|
||||
res += " " + boardId + " = " + boards.get(boardId) + "\n";
|
||||
return res + "}";
|
||||
}
|
||||
}
|
||||
|
@@ -1,13 +1,5 @@
|
||||
package processing.app.helpers;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import processing.app.BaseNoGui;
|
||||
import processing.app.I18n;
|
||||
import processing.app.PreferencesData;
|
||||
@@ -16,34 +8,59 @@ import processing.app.debug.TargetPackage;
|
||||
import processing.app.debug.TargetPlatform;
|
||||
import processing.app.legacy.PApplet;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static processing.app.I18n._;
|
||||
|
||||
public class CommandlineParser {
|
||||
|
||||
protected static enum ACTION { GUI, NOOP, VERIFY, UPLOAD, GET_PREF };
|
||||
private enum ACTION {
|
||||
GUI, NOOP, VERIFY("--verify"), UPLOAD("--upload"), GET_PREF("--get-pref"), INSTALL_BOARD("--install-boards"), INSTALL_LIBRARY("--install-library");
|
||||
|
||||
private final String value;
|
||||
|
||||
ACTION() {
|
||||
this.value = null;
|
||||
}
|
||||
|
||||
ACTION(String value) {
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
|
||||
private ACTION action = ACTION.GUI;
|
||||
private boolean doVerboseBuild = false;
|
||||
private boolean doVerboseUpload = false;
|
||||
private boolean doUseProgrammer = false;
|
||||
private boolean preserveTempFiles;
|
||||
private boolean noUploadPort = false;
|
||||
private boolean forceSavePrefs = false;
|
||||
private String getPref = null;
|
||||
private String getPref;
|
||||
private String boardToInstall;
|
||||
private String libraryToInstall;
|
||||
private List<String> filenames = new LinkedList<String>();
|
||||
|
||||
public static CommandlineParser newCommandlineParser(String[] args) {
|
||||
return new CommandlineParser(args);
|
||||
}
|
||||
|
||||
|
||||
private CommandlineParser(String[] args) {
|
||||
parseArguments(args);
|
||||
checkAction();
|
||||
}
|
||||
|
||||
|
||||
private void parseArguments(String[] args) {
|
||||
// Map of possible actions and corresponding options
|
||||
final Map<String, ACTION> actions = new HashMap<String, ACTION>();
|
||||
actions.put("--verify", ACTION.VERIFY);
|
||||
actions.put("--upload", ACTION.UPLOAD);
|
||||
actions.put("--get-pref", ACTION.GET_PREF);
|
||||
actions.put("--install-boards", ACTION.INSTALL_BOARD);
|
||||
actions.put("--install-library", ACTION.INSTALL_LIBRARY);
|
||||
|
||||
// Check if any files were passed in on the command line
|
||||
for (int i = 0; i < args.length; i++) {
|
||||
@@ -56,10 +73,25 @@ public class CommandlineParser {
|
||||
}
|
||||
if (a == ACTION.GET_PREF) {
|
||||
i++;
|
||||
if (i >= args.length)
|
||||
BaseNoGui.showError(null, _("Argument required for --get-pref"), 3);
|
||||
if (i >= args.length) {
|
||||
BaseNoGui.showError(null, I18n.format(_("Argument required for {0}"), a.value), 3);
|
||||
}
|
||||
getPref = args[i];
|
||||
}
|
||||
if (a == ACTION.INSTALL_BOARD) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
BaseNoGui.showError(null, I18n.format(_("Argument required for {0}"), a.value), 3);
|
||||
}
|
||||
boardToInstall = args[i];
|
||||
}
|
||||
if (a == ACTION.INSTALL_LIBRARY) {
|
||||
i++;
|
||||
if (i >= args.length) {
|
||||
BaseNoGui.showError(null, I18n.format(_("Argument required for {0}"), a.value), 3);
|
||||
}
|
||||
libraryToInstall = args[i];
|
||||
}
|
||||
action = a;
|
||||
continue;
|
||||
}
|
||||
@@ -74,6 +106,12 @@ public class CommandlineParser {
|
||||
action = ACTION.NOOP;
|
||||
continue;
|
||||
}
|
||||
if (args[i].equals("--preserve-temp-files")) {
|
||||
preserveTempFiles = true;
|
||||
if (action == ACTION.GUI)
|
||||
action = ACTION.NOOP;
|
||||
continue;
|
||||
}
|
||||
if (args[i].equals("--verbose-build")) {
|
||||
doVerboseBuild = true;
|
||||
if (action == ACTION.GUI)
|
||||
@@ -164,7 +202,7 @@ public class CommandlineParser {
|
||||
filenames.add(args[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void checkAction() {
|
||||
if ((action == ACTION.UPLOAD || action == ACTION.VERIFY) && filenames.size() != 1)
|
||||
BaseNoGui.showError(null, _("Must specify exactly one sketch file"), 3);
|
||||
@@ -179,7 +217,7 @@ public class CommandlineParser {
|
||||
private void processBoardArgument(String selectBoard) {
|
||||
// No board selected? Nothing to do
|
||||
if (selectBoard == null)
|
||||
return;
|
||||
return;
|
||||
|
||||
String[] split = selectBoard.split(":", 4);
|
||||
|
||||
@@ -251,27 +289,27 @@ public class CommandlineParser {
|
||||
public List<String> getFilenames() {
|
||||
return filenames;
|
||||
}
|
||||
|
||||
|
||||
public boolean isGetPrefMode() {
|
||||
return action == ACTION.GET_PREF;
|
||||
}
|
||||
|
||||
|
||||
public boolean isGuiMode() {
|
||||
return action == ACTION.GUI;
|
||||
}
|
||||
|
||||
|
||||
public boolean isNoOpMode() {
|
||||
return action == ACTION.NOOP;
|
||||
}
|
||||
|
||||
|
||||
public boolean isUploadMode() {
|
||||
return action == ACTION.UPLOAD;
|
||||
}
|
||||
|
||||
|
||||
public boolean isVerifyMode() {
|
||||
return action == ACTION.VERIFY;
|
||||
}
|
||||
|
||||
|
||||
public boolean isVerifyOrUploadMode() {
|
||||
return isVerifyMode() || isUploadMode();
|
||||
}
|
||||
@@ -284,4 +322,23 @@ public class CommandlineParser {
|
||||
return noUploadPort;
|
||||
}
|
||||
|
||||
public boolean isInstallBoard() {
|
||||
return action == ACTION.INSTALL_BOARD;
|
||||
}
|
||||
|
||||
public boolean isInstallLibrary() {
|
||||
return action == ACTION.INSTALL_LIBRARY;
|
||||
}
|
||||
|
||||
public String getBoardToInstall() {
|
||||
return this.boardToInstall;
|
||||
}
|
||||
|
||||
public String getLibraryToInstall() {
|
||||
return libraryToInstall;
|
||||
}
|
||||
|
||||
public boolean isPreserveTempFiles() {
|
||||
return preserveTempFiles;
|
||||
}
|
||||
}
|
||||
|
@@ -73,17 +73,28 @@ public class FileUtils {
|
||||
}
|
||||
|
||||
public static void recursiveDelete(File file) {
|
||||
if (file == null)
|
||||
if (file == null) {
|
||||
return;
|
||||
}
|
||||
if (file.isDirectory()) {
|
||||
for (File current : file.listFiles())
|
||||
File[] files = file.listFiles();
|
||||
if (files == null) {
|
||||
return;
|
||||
}
|
||||
for (File current : files) {
|
||||
recursiveDelete(current);
|
||||
}
|
||||
}
|
||||
file.delete();
|
||||
}
|
||||
|
||||
public static File createTempFolder() throws IOException {
|
||||
File tmpFolder = new File(System.getProperty("java.io.tmpdir"), "arduino_" + new Random().nextInt(1000000));
|
||||
return createTempFolderIn(new File(System.getProperty("java.io.tmpdir")));
|
||||
}
|
||||
|
||||
public static File createTempFolderIn(File parent) throws IOException {
|
||||
File tmpFolder = new File(parent, "arduino_"
|
||||
+ new Random().nextInt(1000000));
|
||||
if (!tmpFolder.mkdir()) {
|
||||
throw new IOException("Unable to create temp folder " + tmpFolder);
|
||||
}
|
||||
@@ -249,5 +260,21 @@ public class FileUtils {
|
||||
return result;
|
||||
}
|
||||
|
||||
public static File newFile(File parent, String... parts) {
|
||||
File result = parent;
|
||||
for (String part : parts) {
|
||||
result = new File(result, part);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public static boolean deleteIfExists(File file) {
|
||||
if (file == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return file.delete();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -11,7 +11,7 @@ public abstract class NetUtils {
|
||||
|
||||
private static boolean isReachableByEcho(InetAddress address) {
|
||||
try {
|
||||
return address.isReachable(100);
|
||||
return address.isReachable(300);
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
}
|
||||
@@ -38,7 +38,7 @@ public abstract class NetUtils {
|
||||
Socket socket = null;
|
||||
try {
|
||||
socket = new Socket();
|
||||
socket.connect(new InetSocketAddress(address, port), 300);
|
||||
socket.connect(new InetSocketAddress(address, port), 1000);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
|
@@ -21,18 +21,14 @@
|
||||
*/
|
||||
package processing.app.helpers;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import processing.app.legacy.PApplet;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.SortedSet;
|
||||
import java.util.TreeSet;
|
||||
|
||||
import processing.app.legacy.PApplet;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class PreferencesMap extends LinkedHashMap<String, String> {
|
||||
|
||||
@@ -71,7 +67,15 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
|
||||
* @throws IOException
|
||||
*/
|
||||
public void load(File file) throws IOException {
|
||||
load(new FileInputStream(file));
|
||||
FileInputStream fileInputStream = null;
|
||||
try {
|
||||
fileInputStream = new FileInputStream(file);
|
||||
load(fileInputStream);
|
||||
} finally {
|
||||
if (fileInputStream != null) {
|
||||
fileInputStream.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected String processPlatformSuffix(String key, String suffix, boolean isCurrentPlatform) {
|
||||
@@ -311,7 +315,7 @@ public class PreferencesMap extends LinkedHashMap<String, String> {
|
||||
* insensitive compared), <b>false</b> in any other case
|
||||
*/
|
||||
public boolean getBoolean(String key) {
|
||||
return new Boolean(get(key));
|
||||
return Boolean.valueOf(get(key));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -26,4 +26,18 @@ public class StringUtils {
|
||||
String regex = pattern.replace("?", ".?").replace("*", ".*?");
|
||||
return input.matches(regex);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the string without trailing whitespace characters
|
||||
*
|
||||
* @param s
|
||||
* @return
|
||||
*/
|
||||
public static String rtrim(String s) {
|
||||
int i = s.length() - 1;
|
||||
while (i >= 0 && Character.isWhitespace(s.charAt(i))) {
|
||||
i--;
|
||||
}
|
||||
return s.substring(0, i + 1);
|
||||
}
|
||||
}
|
||||
|
@@ -32,11 +32,17 @@ import java.io.FilenameFilter;
|
||||
*/
|
||||
public class OnlyDirs implements FilenameFilter {
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
if (name.charAt(0) == '.')
|
||||
return false;
|
||||
if (name.equals("CVS"))
|
||||
return false;
|
||||
return new File(dir, name).isDirectory();
|
||||
}
|
||||
public boolean accept(File dir, String name) {
|
||||
if (name.charAt(0) == '.')
|
||||
return false;
|
||||
if (name.equals("CVS"))
|
||||
return false;
|
||||
return new File(dir, name).isDirectory();
|
||||
}
|
||||
|
||||
/**
|
||||
* An handy pre-instantiated object
|
||||
*/
|
||||
public static final OnlyDirs ONLY_DIRS = new OnlyDirs();
|
||||
|
||||
}
|
||||
|
@@ -29,13 +29,15 @@ public class OnlyFilesWithExtension implements FilenameFilter {
|
||||
String extensions[];
|
||||
|
||||
public OnlyFilesWithExtension(String... ext) {
|
||||
extensions = ext;
|
||||
this.extensions = ext;
|
||||
}
|
||||
|
||||
public boolean accept(File dir, String name) {
|
||||
for (String ext : extensions)
|
||||
if (name.endsWith(ext))
|
||||
for (String ext : extensions) {
|
||||
if (name.endsWith(ext)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,6 @@
|
||||
package processing.app.legacy;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.io.PrintWriter;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.io.*;
|
||||
import java.text.NumberFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.StringTokenizer;
|
||||
@@ -276,15 +266,26 @@ public class PApplet {
|
||||
}
|
||||
|
||||
static public String[] loadStrings(File file) {
|
||||
InputStream is = createInput(file);
|
||||
if (is != null) return loadStrings(is);
|
||||
return null;
|
||||
InputStream is = null;
|
||||
try {
|
||||
is = createInput(file);
|
||||
if (is != null) return loadStrings(is);
|
||||
return null;
|
||||
} finally {
|
||||
if (is != null) {
|
||||
try {
|
||||
is.close();
|
||||
} catch (IOException e) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static public String[] loadStrings(InputStream input) {
|
||||
BufferedReader reader = null;
|
||||
try {
|
||||
BufferedReader reader =
|
||||
new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
reader = new BufferedReader(new InputStreamReader(input, "UTF-8"));
|
||||
|
||||
String lines[] = new String[100];
|
||||
int lineCount = 0;
|
||||
@@ -297,7 +298,6 @@ public class PApplet {
|
||||
}
|
||||
lines[lineCount++] = line;
|
||||
}
|
||||
reader.close();
|
||||
|
||||
if (lineCount == lines.length) {
|
||||
return lines;
|
||||
@@ -311,6 +311,15 @@ public class PApplet {
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
//throw new RuntimeException("Error inside loadStrings()");
|
||||
} finally {
|
||||
if (reader != null) {
|
||||
try {
|
||||
reader.close();
|
||||
} catch (IOException e) {
|
||||
//ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -321,14 +330,29 @@ public class PApplet {
|
||||
|
||||
|
||||
static public void saveStrings(File file, String strings[]) {
|
||||
saveStrings(createOutput(file), strings);
|
||||
OutputStream outputStream = null;
|
||||
try {
|
||||
outputStream = createOutput(file);
|
||||
saveStrings(outputStream, strings);
|
||||
} finally {
|
||||
if (outputStream != null) {
|
||||
try {
|
||||
outputStream.close();
|
||||
} catch (IOException e) {
|
||||
//noop
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static public void saveStrings(OutputStream output, String strings[]) {
|
||||
PrintWriter writer = createWriter(output);
|
||||
for (int i = 0; i < strings.length; i++) {
|
||||
writer.println(strings[i]);
|
||||
if (writer == null) {
|
||||
return;
|
||||
}
|
||||
for (String string : strings) {
|
||||
writer.println(string);
|
||||
}
|
||||
writer.flush();
|
||||
writer.close();
|
||||
|
151
arduino-core/src/processing/app/linux/GTKLookAndFeelFixer.java
Normal file
151
arduino-core/src/processing/app/linux/GTKLookAndFeelFixer.java
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Arduino 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*
|
||||
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
|
||||
*/
|
||||
|
||||
package processing.app.linux;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
public class GTKLookAndFeelFixer {
|
||||
|
||||
/*
|
||||
* All functions of this class courtesy of Klaus Reimer
|
||||
* https://www.ailis.de/~k/archives/67-Workaround-for-borderless-Java-Swing-menus-on-Linux.html
|
||||
*/
|
||||
|
||||
/*
|
||||
* This is free and unencumbered software released into the public domain.
|
||||
*
|
||||
* Anyone is free to copy, modify, publish, use, compile, sell, or
|
||||
* distribute this software, either in source code form or as a compiled
|
||||
* binary, for any purpose, commercial or non-commercial, and by any
|
||||
* means.
|
||||
*
|
||||
* In jurisdictions that recognize copyright laws, the author or authors
|
||||
* of this software dedicate any and all copyright interest in the
|
||||
* software to the public domain. We make this dedication for the benefit
|
||||
* of the public at large and to the detriment of our heirs and
|
||||
* successors. We intend this dedication to be an overt act of
|
||||
* relinquishment in perpetuity of all present and future rights to this
|
||||
* software under copyright law.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
||||
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* For more information, please refer to <http://unlicense.org/>
|
||||
*/
|
||||
|
||||
/**
|
||||
* Swing menus are looking pretty bad on Linux when the GTK LaF is used (See
|
||||
* bug #6925412). It will most likely never be fixed anytime soon so this
|
||||
* method provides a workaround for it. It uses reflection to change the GTK
|
||||
* style objects of Swing so popup menu borders have a minimum thickness of
|
||||
* 1 and menu separators have a minimum vertical thickness of 1.
|
||||
*/
|
||||
public static void installGtkPopupBugWorkaround() {
|
||||
// Get current look-and-feel implementation class
|
||||
LookAndFeel laf = UIManager.getLookAndFeel();
|
||||
Class<?> lafClass = laf.getClass();
|
||||
|
||||
// Do nothing when not using the problematic LaF
|
||||
if (!lafClass.getName().equals("com.sun.java.swing.plaf.gtk.GTKLookAndFeel")) {
|
||||
return;
|
||||
}
|
||||
|
||||
// We do reflection from here on. Failure is silently ignored. The
|
||||
// workaround is simply not installed when something goes wrong here
|
||||
try {
|
||||
// Access the GTK style factory
|
||||
Field field = lafClass.getDeclaredField("styleFactory");
|
||||
boolean accessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
Object styleFactory = field.get(laf);
|
||||
field.setAccessible(accessible);
|
||||
|
||||
// Fix the horizontal and vertical thickness of popup menu style
|
||||
Object style = getGtkStyle(styleFactory, new JPopupMenu(), "POPUP_MENU");
|
||||
fixGtkThickness(style, "yThickness");
|
||||
fixGtkThickness(style, "xThickness");
|
||||
|
||||
// Fix the vertical thickness of the popup menu separator style
|
||||
style = getGtkStyle(styleFactory, new JSeparator(), "POPUP_MENU_SEPARATOR");
|
||||
fixGtkThickness(style, "yThickness");
|
||||
} catch (Exception e) {
|
||||
// Silently ignored. Workaround can't be applied.
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by installGtkPopupBugWorkaround to fix the thickness
|
||||
* of a GTK style field by setting it to a minimum value of 1.
|
||||
*
|
||||
* @param style The GTK style object.
|
||||
* @param fieldName The field name.
|
||||
* @throws Exception When reflection fails.
|
||||
*/
|
||||
private static void fixGtkThickness(Object style, String fieldName) throws Exception {
|
||||
Field field = style.getClass().getDeclaredField(fieldName);
|
||||
boolean accessible = field.isAccessible();
|
||||
field.setAccessible(true);
|
||||
field.setInt(style, Math.max(1, field.getInt(style)));
|
||||
field.setAccessible(accessible);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called internally by installGtkPopupBugWorkaround. Returns a specific
|
||||
* GTK style object.
|
||||
*
|
||||
* @param styleFactory The GTK style factory.
|
||||
* @param component The target component of the style.
|
||||
* @param regionName The name of the target region of the style.
|
||||
* @return The GTK style.
|
||||
* @throws Exception When reflection fails.
|
||||
*/
|
||||
private static Object getGtkStyle(Object styleFactory, JComponent component, String regionName) throws Exception {
|
||||
// Create the region object
|
||||
Class<?> regionClass = Class.forName("javax.swing.plaf.synth.Region");
|
||||
Field field = regionClass.getField(regionName);
|
||||
Object region = field.get(regionClass);
|
||||
|
||||
// Get and return the style
|
||||
Class<?> styleFactoryClass = styleFactory.getClass();
|
||||
Method method = styleFactoryClass.getMethod("getStyle", JComponent.class, regionClass);
|
||||
boolean accessible = method.isAccessible();
|
||||
method.setAccessible(true);
|
||||
Object style = method.invoke(styleFactory, component, region);
|
||||
method.setAccessible(accessible);
|
||||
return style;
|
||||
}
|
||||
}
|
@@ -26,10 +26,12 @@ import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.Executor;
|
||||
import processing.app.PreferencesData;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.app.tools.ExternalProcessExecutor;
|
||||
import processing.app.legacy.PConstants;
|
||||
import processing.app.tools.CollectStdOutExecutor;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -42,17 +44,7 @@ public class Platform extends processing.app.Platform {
|
||||
// TODO Need to be smarter here since KDE people ain't gonna like that GTK.
|
||||
// It may even throw a weird exception at 'em for their trouble.
|
||||
public void setLookAndFeel() throws Exception {
|
||||
// Linux is by default even uglier than metal (Motif?).
|
||||
// Actually, i'm using native menus, so they're even uglier
|
||||
// and Motif-looking (Lesstif?). Ick. Need to fix this.
|
||||
//String lfname = UIManager.getCrossPlatformLookAndFeelClassName();
|
||||
//UIManager.setLookAndFeel(lfname);
|
||||
|
||||
// For 0120, trying out the gtk+ look and feel as the default.
|
||||
// This is available in Java 1.4.2 and later, and it can't possibly
|
||||
// be any worse than Metal. (Ocean might also work, but that's for
|
||||
// Java 1.5, and we aren't going there yet)
|
||||
//UIManager.setLookAndFeel("com.sun.java.swing.plaf.gtk.GTKLookAndFeel");
|
||||
GTKLookAndFeelFixer.installGtkPopupBugWorkaround();
|
||||
}
|
||||
|
||||
|
||||
@@ -130,8 +122,9 @@ public class Platform extends processing.app.Platform {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
|
||||
assert packages != null;
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Executor executor = new ExternalProcessExecutor(baos);
|
||||
Executor executor = new CollectStdOutExecutor(baos);
|
||||
|
||||
try {
|
||||
CommandLine toDevicePath = CommandLine.parse("udevadm info -q path -n " + serial);
|
||||
|
@@ -26,12 +26,12 @@ import cc.arduino.packages.BoardPort;
|
||||
import com.apple.eio.FileManager;
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.Executor;
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.app.tools.ExternalProcessExecutor;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.legacy.PConstants;
|
||||
import processing.app.tools.CollectStdOutExecutor;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.*;
|
||||
import java.lang.reflect.Method;
|
||||
@@ -45,12 +45,9 @@ import java.util.List;
|
||||
*/
|
||||
public class Platform extends processing.app.Platform {
|
||||
|
||||
private String osArch;
|
||||
|
||||
public void setLookAndFeel() throws Exception {
|
||||
// Use the Quaqua L & F on OS X to make JFileChooser less awful
|
||||
UIManager.setLookAndFeel("ch.randelshofer.quaqua.QuaquaLookAndFeel");
|
||||
// undo quaqua trying to fix the margins, since we've already
|
||||
// hacked that in, bit by bit, over the years
|
||||
UIManager.put("Component.visualMargin", new Insets(1, 1, 1, 1));
|
||||
}
|
||||
|
||||
public Platform() {
|
||||
@@ -59,35 +56,18 @@ public class Platform extends processing.app.Platform {
|
||||
Toolkit.getDefaultToolkit();
|
||||
}
|
||||
|
||||
public void init() {
|
||||
public void init() throws IOException {
|
||||
System.setProperty("apple.laf.useScreenMenuBar", "true");
|
||||
/*
|
||||
try {
|
||||
String name = "processing.app.macosx.ThinkDifferent";
|
||||
Class osxAdapter = ClassLoader.getSystemClassLoader().loadClass(name);
|
||||
|
||||
Class[] defArgs = { Base.class };
|
||||
Method registerMethod = osxAdapter.getDeclaredMethod("register", defArgs);
|
||||
if (registerMethod != null) {
|
||||
Object[] args = { this };
|
||||
registerMethod.invoke(osxAdapter, args);
|
||||
}
|
||||
} catch (NoClassDefFoundError e) {
|
||||
// This will be thrown first if the OSXAdapter is loaded on a system without the EAWT
|
||||
// because OSXAdapter extends ApplicationAdapter in its def
|
||||
System.err.println("This version of Mac OS X does not support the Apple EAWT." +
|
||||
"Application Menu handling has been disabled (" + e + ")");
|
||||
discoverRealOsArch();
|
||||
}
|
||||
|
||||
} catch (ClassNotFoundException e) {
|
||||
// This shouldn't be reached; if there's a problem with the OSXAdapter
|
||||
// we should get the above NoClassDefFoundError first.
|
||||
System.err.println("This version of Mac OS X does not support the Apple EAWT. " +
|
||||
"Application Menu handling has been disabled (" + e + ")");
|
||||
} catch (Exception e) {
|
||||
System.err.println("Exception while loading BaseOSX:");
|
||||
e.printStackTrace();
|
||||
}
|
||||
*/
|
||||
private void discoverRealOsArch() throws IOException {
|
||||
CommandLine uname = CommandLine.parse("uname -m");
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
CollectStdOutExecutor executor = new CollectStdOutExecutor(baos);
|
||||
executor.execute(uname);
|
||||
osArch = StringUtils.trim(new String(baos.toByteArray()));
|
||||
}
|
||||
|
||||
|
||||
@@ -115,7 +95,7 @@ public class Platform extends processing.app.Platform {
|
||||
|
||||
public void openURL(String url) throws Exception {
|
||||
if (PApplet.javaVersion < 1.6f) {
|
||||
if (url.startsWith("http://")) {
|
||||
if (url.startsWith("http")) {
|
||||
// formerly com.apple.eio.FileManager.openURL(url);
|
||||
// but due to deprecation, instead loading dynamically
|
||||
try {
|
||||
@@ -139,7 +119,7 @@ public class Platform extends processing.app.Platform {
|
||||
|
||||
// for Java 1.6, replacing with java.awt.Desktop.browse()
|
||||
// and java.awt.Desktop.open()
|
||||
if (url.startsWith("http://")) { // browse to a location
|
||||
if (url.startsWith("http")) { // browse to a location
|
||||
Method browseMethod =
|
||||
desktopClass.getMethod("browse", new Class[] { URI.class });
|
||||
browseMethod.invoke(desktop, new Object[] { new URI(url) });
|
||||
@@ -211,6 +191,7 @@ public class Platform extends processing.app.Platform {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
|
||||
assert packages != null;
|
||||
if (devicesListOutput == null) {
|
||||
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
|
||||
}
|
||||
@@ -231,7 +212,7 @@ public class Platform extends processing.app.Platform {
|
||||
@Override
|
||||
public String preListAllCandidateDevices() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Executor executor = new ExternalProcessExecutor(baos);
|
||||
Executor executor = new CollectStdOutExecutor(baos);
|
||||
|
||||
try {
|
||||
CommandLine toDevicePath = CommandLine.parse("/usr/sbin/system_profiler SPUSBDataType");
|
||||
@@ -250,11 +231,16 @@ public class Platform extends processing.app.Platform {
|
||||
|
||||
List<BoardPort> filteredPorts = new LinkedList<BoardPort>();
|
||||
for (BoardPort port : ports) {
|
||||
if (!port.getAddress().startsWith("/dev/cu.")) {
|
||||
if (!port.getAddress().startsWith("/dev/tty.")) {
|
||||
filteredPorts.add(port);
|
||||
}
|
||||
}
|
||||
|
||||
return filteredPorts;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getOsArch() {
|
||||
return osArch;
|
||||
}
|
||||
}
|
||||
|
126
arduino-core/src/processing/app/packages/LegacyUserLibrary.java
Normal file
126
arduino-core/src/processing/app/packages/LegacyUserLibrary.java
Normal file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2014 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
package processing.app.packages;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
import cc.arduino.contributions.libraries.ContributedLibraryReference;
|
||||
|
||||
public class LegacyUserLibrary extends UserLibrary {
|
||||
|
||||
private String name;
|
||||
|
||||
public static LegacyUserLibrary create(File libFolder) {
|
||||
// construct an old style library
|
||||
LegacyUserLibrary res = new LegacyUserLibrary();
|
||||
res.setInstalledFolder(libFolder);
|
||||
res.setInstalled(true);
|
||||
res.layout = LibraryLayout.FLAT;
|
||||
res.name = libFolder.getName();
|
||||
return res;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArchitectures() {
|
||||
return Arrays.asList("*");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParagraph() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSentence() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getWebsite() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCategory() {
|
||||
return "Uncategorized";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLicense() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaintainer() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChecksum() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContributedLibraryReference> getRequires() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "LegacyLibrary:" + name + "\n";
|
||||
}
|
||||
|
||||
}
|
@@ -1,14 +1,42 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2014 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
package processing.app.packages;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import processing.app.helpers.FileUtils;
|
||||
|
||||
@SuppressWarnings("serial")
|
||||
public class LibraryList extends ArrayList<Library> {
|
||||
public class LibraryList extends LinkedList<UserLibrary> {
|
||||
|
||||
public LibraryList(LibraryList libs) {
|
||||
super(libs);
|
||||
@@ -18,53 +46,46 @@ public class LibraryList extends ArrayList<Library> {
|
||||
super();
|
||||
}
|
||||
|
||||
public Library getByName(String name) {
|
||||
for (Library l : this)
|
||||
public LibraryList(List<UserLibrary> ideLibs) {
|
||||
super(ideLibs);
|
||||
}
|
||||
|
||||
public UserLibrary getByName(String name) {
|
||||
for (UserLibrary l : this)
|
||||
if (l.getName().equals(name))
|
||||
return l;
|
||||
return null;
|
||||
}
|
||||
|
||||
public void addOrReplace(Library lib) {
|
||||
Library l = getByName(lib.getName());
|
||||
if (l != null)
|
||||
remove(l);
|
||||
public void addOrReplace(UserLibrary lib) {
|
||||
remove(lib);
|
||||
add(lib);
|
||||
}
|
||||
|
||||
public void addOrReplaceAll(Collection<? extends Library> c) {
|
||||
for (Library l : c)
|
||||
addOrReplace(l);
|
||||
|
||||
public void remove(UserLibrary lib) {
|
||||
UserLibrary l = getByName(lib.getName());
|
||||
if (l != null)
|
||||
super.remove(l);
|
||||
}
|
||||
|
||||
public void sort() {
|
||||
Collections.sort(this, Library.CASE_INSENSITIVE_ORDER);
|
||||
}
|
||||
|
||||
public Library search(String name, String arch) {
|
||||
for (Library lib : this) {
|
||||
if (!lib.getName().equals(name))
|
||||
continue;
|
||||
if (!lib.supportsArchitecture(arch))
|
||||
continue;
|
||||
return lib;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public LibraryList filterByArchitecture(String reqArch) {
|
||||
LibraryList res = new LibraryList();
|
||||
for (Library lib : this)
|
||||
if (lib.supportsArchitecture(reqArch))
|
||||
res.add(lib);
|
||||
return res;
|
||||
Collections.sort(this, UserLibrary.CASE_INSENSITIVE_ORDER);
|
||||
}
|
||||
|
||||
public LibraryList filterLibrariesInSubfolder(File subFolder) {
|
||||
LibraryList res = new LibraryList();
|
||||
for (Library lib : this)
|
||||
if (FileUtils.isSubDirectory(subFolder, lib.getFolder()))
|
||||
for (UserLibrary lib : this) {
|
||||
if (FileUtils.isSubDirectory(subFolder, lib.getInstalledFolder())) {
|
||||
res.add(lib);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public boolean hasLibrary(UserLibrary lib) {
|
||||
for (UserLibrary l : this)
|
||||
if (l == lib) return true;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,16 +1,46 @@
|
||||
/*
|
||||
* This file is part of Arduino.
|
||||
*
|
||||
* Copyright 2014 Arduino LLC (http://www.arduino.cc/)
|
||||
*
|
||||
* Arduino 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*
|
||||
* As a special exception, you may use this file as part of a free software
|
||||
* library without restriction. Specifically, if other files instantiate
|
||||
* templates or use macros or inline functions from this file, or you compile
|
||||
* this file and link it with other files to produce an executable, this
|
||||
* file does not by itself cause the resulting executable to be covered by
|
||||
* the GNU General Public License. This exception does not however
|
||||
* invalidate any other reasons why the executable file might be covered by
|
||||
* the GNU General Public License.
|
||||
*/
|
||||
package processing.app.packages;
|
||||
|
||||
import cc.arduino.contributions.libraries.ContributedLibrary;
|
||||
import cc.arduino.contributions.libraries.ContributedLibraryReference;
|
||||
import processing.app.helpers.FileUtils;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import processing.app.helpers.FileUtils;
|
||||
import processing.app.helpers.PreferencesMap;
|
||||
|
||||
public class Library {
|
||||
public class UserLibrary extends ContributedLibrary {
|
||||
|
||||
private String name;
|
||||
private String version;
|
||||
@@ -18,44 +48,23 @@ public class Library {
|
||||
private String maintainer;
|
||||
private String sentence;
|
||||
private String paragraph;
|
||||
private String url;
|
||||
private String website;
|
||||
private String category;
|
||||
private String license;
|
||||
private List<String> architectures;
|
||||
private File folder;
|
||||
private boolean isLegacy;
|
||||
|
||||
private enum LibraryLayout { FLAT, RECURSIVE };
|
||||
private LibraryLayout layout;
|
||||
private List<String> types;
|
||||
private List<String> declaredTypes;
|
||||
|
||||
private static final List<String> MANDATORY_PROPERTIES = Arrays
|
||||
.asList(new String[] { "name", "version", "author", "maintainer",
|
||||
"sentence", "paragraph", "url" });
|
||||
.asList(new String[]{"name", "version", "author", "maintainer",
|
||||
"sentence", "paragraph", "url"});
|
||||
|
||||
private static final List<String> CATEGORIES = Arrays.asList(new String[] {
|
||||
"Display", "Communication", "Signal Input/Output", "Sensors",
|
||||
"Device Control", "Timing", "Data Storage", "Data Processing", "Other",
|
||||
"Uncategorized" });
|
||||
private static final List<String> CATEGORIES = Arrays.asList(new String[]{
|
||||
"Display", "Communication", "Signal Input/Output", "Sensors",
|
||||
"Device Control", "Timing", "Data Storage", "Data Processing", "Other",
|
||||
"Uncategorized"});
|
||||
|
||||
/**
|
||||
* Scans inside a folder and create a Library object out of it. Automatically
|
||||
* detects legacy libraries. Automatically fills metadata from
|
||||
* library.properties file if found.
|
||||
*
|
||||
* @param libFolder
|
||||
* @return
|
||||
*/
|
||||
static public Library create(File libFolder) throws IOException {
|
||||
// A library is considered "new" if it contains a file called
|
||||
// "library.properties"
|
||||
File check = new File(libFolder, "library.properties");
|
||||
if (!check.exists() || !check.isFile())
|
||||
return createLegacyLibrary(libFolder);
|
||||
else
|
||||
return createLibrary(libFolder);
|
||||
}
|
||||
|
||||
private static Library createLibrary(File libFolder) throws IOException {
|
||||
public static UserLibrary create(File libFolder) throws IOException {
|
||||
// Parse metadata
|
||||
File propertiesFile = new File(libFolder, "library.properties");
|
||||
PreferencesMap properties = new PreferencesMap();
|
||||
@@ -66,16 +75,16 @@ public class Library {
|
||||
|
||||
// Compatibility with 1.5 rev.1 libraries:
|
||||
// "email" field changed to "maintainer"
|
||||
if (!properties.containsKey("maintainer") &&
|
||||
properties.containsKey("email"))
|
||||
if (!properties.containsKey("maintainer") && properties.containsKey("email")) {
|
||||
properties.put("maintainer", properties.get("email"));
|
||||
}
|
||||
|
||||
// Compatibility with 1.5 rev.1 libraries:
|
||||
// "arch" folder no longer supported
|
||||
File archFolder = new File(libFolder, "arch");
|
||||
if (archFolder.isDirectory())
|
||||
throw new IOException("'arch' folder is no longer supported! See "
|
||||
+ "http://goo.gl/gfFJzU for more information");
|
||||
+ "http://goo.gl/gfFJzU for more information");
|
||||
|
||||
// Check mandatory properties
|
||||
for (String p : MANDATORY_PROPERTIES)
|
||||
@@ -93,7 +102,7 @@ public class Library {
|
||||
File utilFolder = new File(libFolder, "utility");
|
||||
if (utilFolder.exists() && utilFolder.isDirectory()) {
|
||||
throw new IOException(
|
||||
"Library can't use both 'src' and 'utility' folders.");
|
||||
"Library can't use both 'src' and 'utility' folders.");
|
||||
}
|
||||
} else {
|
||||
// Layout with source code on library's root and "utility" folders
|
||||
@@ -104,8 +113,7 @@ public class Library {
|
||||
for (File file : libFolder.listFiles()) {
|
||||
if (file.isDirectory()) {
|
||||
if (FileUtils.isSCCSOrHiddenFile(file)) {
|
||||
System.out.println("WARNING: Spurious " + file.getName() +
|
||||
" folder in '" + properties.get("name") + "' library");
|
||||
System.out.println("WARNING: Spurious " + file.getName() + " folder in '" + properties.get("name") + "' library");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
@@ -123,110 +131,88 @@ public class Library {
|
||||
if (category == null)
|
||||
category = "Uncategorized";
|
||||
if (!CATEGORIES.contains(category)) {
|
||||
category = "Uncategorized";
|
||||
System.out.println("WARNING: Category '" + category + "' in library " +
|
||||
properties.get("name") + " is not valid. Setting to 'Uncategorized'");
|
||||
properties.get("name") + " is not valid. Setting to 'Uncategorized'");
|
||||
category = "Uncategorized";
|
||||
}
|
||||
|
||||
String license = properties.get("license");
|
||||
if (license == null)
|
||||
if (license == null) {
|
||||
license = "Unspecified";
|
||||
}
|
||||
|
||||
Library res = new Library();
|
||||
res.folder = libFolder;
|
||||
String types = properties.get("types");
|
||||
if (types == null) {
|
||||
types = "Contributed";
|
||||
}
|
||||
List<String> typesList = new LinkedList<String>();
|
||||
for (String type : types.split(",")) {
|
||||
typesList.add(type.trim());
|
||||
}
|
||||
|
||||
UserLibrary res = new UserLibrary();
|
||||
res.setInstalledFolder(libFolder);
|
||||
res.setInstalled(true);
|
||||
res.name = properties.get("name").trim();
|
||||
res.version = properties.get("version").trim();
|
||||
res.author = properties.get("author").trim();
|
||||
res.maintainer = properties.get("maintainer").trim();
|
||||
res.sentence = properties.get("sentence").trim();
|
||||
res.paragraph = properties.get("paragraph").trim();
|
||||
res.url = properties.get("url").trim();
|
||||
res.website = properties.get("url").trim();
|
||||
res.category = category.trim();
|
||||
res.license = license.trim();
|
||||
res.architectures = archs;
|
||||
res.isLegacy = false;
|
||||
res.layout = layout;
|
||||
res.declaredTypes = typesList;
|
||||
return res;
|
||||
}
|
||||
|
||||
private static Library createLegacyLibrary(File libFolder) {
|
||||
// construct an old style library
|
||||
Library res = new Library();
|
||||
res.folder = libFolder;
|
||||
res.layout = LibraryLayout.FLAT;
|
||||
res.name = libFolder.getName();
|
||||
res.architectures = Arrays.asList("*");
|
||||
res.isLegacy = true;
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <b>true</b> if the library declares to support the specified
|
||||
* architecture (through the "architectures" property field).
|
||||
*
|
||||
* @param reqArch
|
||||
* @return
|
||||
*/
|
||||
public boolean supportsArchitecture(String reqArch) {
|
||||
return architectures.contains(reqArch) || architectures.contains("*");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns <b>true</b> if the library declares to support at least one of the
|
||||
* specified architectures.
|
||||
*
|
||||
* @param reqArchs
|
||||
* A List of architectures to check
|
||||
* @return
|
||||
*/
|
||||
public boolean supportsArchitecture(List<String> reqArchs) {
|
||||
if (reqArchs.contains("*"))
|
||||
return true;
|
||||
for (String reqArch : reqArchs)
|
||||
if (supportsArchitecture(reqArch))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public static final Comparator<Library> CASE_INSENSITIVE_ORDER = new Comparator<Library>() {
|
||||
@Override
|
||||
public int compare(Library o1, Library o2) {
|
||||
return o1.getName().compareToIgnoreCase(o2.getName());
|
||||
}
|
||||
};
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public File getFolder() {
|
||||
return folder;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getArchitectures() {
|
||||
return architectures;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getAuthor() {
|
||||
return author;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getParagraph() {
|
||||
return paragraph;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getSentence() {
|
||||
return sentence;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
@Override
|
||||
public String getWebsite() {
|
||||
return website;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCategory() {
|
||||
return category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<String> getTypes() {
|
||||
return types;
|
||||
}
|
||||
|
||||
public void setTypes(List<String> types) {
|
||||
this.types = types;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getLicense() {
|
||||
return license;
|
||||
}
|
||||
@@ -235,44 +221,82 @@ public class Library {
|
||||
return CATEGORIES;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setCategory(String category) {
|
||||
this.category = category;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getMaintainer() {
|
||||
return maintainer;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getChecksum() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public long getSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getUrl() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getArchiveFileName() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<ContributedLibraryReference> getRequires() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public List<String> getDeclaredTypes() {
|
||||
return declaredTypes;
|
||||
}
|
||||
|
||||
protected enum LibraryLayout {
|
||||
FLAT, RECURSIVE
|
||||
}
|
||||
|
||||
protected LibraryLayout layout;
|
||||
|
||||
public File getSrcFolder() {
|
||||
switch (layout) {
|
||||
case FLAT:
|
||||
return getInstalledFolder();
|
||||
case RECURSIVE:
|
||||
return new File(getInstalledFolder(), "src");
|
||||
default:
|
||||
return null; // Keep compiler happy :-(
|
||||
}
|
||||
}
|
||||
|
||||
public boolean useRecursion() {
|
||||
return (layout == LibraryLayout.RECURSIVE);
|
||||
}
|
||||
|
||||
public File getSrcFolder() {
|
||||
switch (layout) {
|
||||
case FLAT:
|
||||
return folder;
|
||||
case RECURSIVE:
|
||||
return new File(folder, "src");
|
||||
default:
|
||||
return null; // Keep compiler happy :-(
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isLegacy() {
|
||||
return isLegacy;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
String res = "Library:";
|
||||
res += " (name=" + name + ")";
|
||||
res += " (version=" + version + ")";
|
||||
res += " (author=" + author + ")";
|
||||
res += " (maintainer=" + maintainer + ")";
|
||||
res += " (sentence=" + sentence + ")";
|
||||
res += " (paragraph=" + paragraph + ")";
|
||||
res += " (url=" + url + ")";
|
||||
res += " (architectures=" + architectures + ")";
|
||||
String res = "Library: " + name + "\n";
|
||||
res += " (version=" + version + ")\n";
|
||||
res += " (author=" + author + ")\n";
|
||||
res += " (maintainer=" + maintainer + ")\n";
|
||||
res += " (sentence=" + sentence + ")\n";
|
||||
res += " (paragraph=" + paragraph + ")\n";
|
||||
res += " (url=" + website + ")\n";
|
||||
res += " (architectures=" + architectures + ")\n";
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
@@ -42,6 +42,9 @@ import java.util.regex.*;
|
||||
* Class that orchestrates preprocessing p5 syntax into straight Java.
|
||||
*/
|
||||
public class PdePreprocessor {
|
||||
|
||||
private static final String IMPORT_REGEX = "^\\s*#include\\s*[<\"](\\S+)[\">]";
|
||||
|
||||
// stores number of built user-defined function prototypes
|
||||
public int prototypeCount = 0;
|
||||
|
||||
@@ -94,10 +97,9 @@ public class PdePreprocessor {
|
||||
}
|
||||
|
||||
//String importRegexp = "(?:^|\\s|;)(import\\s+)(\\S+)(\\s*;)";
|
||||
String importRegexp = "^\\s*#include\\s*[<\"](\\S+)[\">]";
|
||||
programImports = new ArrayList<String>();
|
||||
|
||||
String[][] pieces = PApplet.matchAll(program, importRegexp);
|
||||
String[][] pieces = PApplet.matchAll(program, IMPORT_REGEX);
|
||||
|
||||
if (pieces != null)
|
||||
for (int i = 0; i < pieces.length; i++)
|
||||
@@ -121,6 +123,19 @@ public class PdePreprocessor {
|
||||
return headerCount + prototypeCount;
|
||||
}
|
||||
|
||||
public static List<String> findIncludes(String code){
|
||||
|
||||
String[][] pieces = PApplet.matchAll(code, IMPORT_REGEX);
|
||||
|
||||
ArrayList programImports = new ArrayList<String>();
|
||||
|
||||
if (pieces != null)
|
||||
for (int i = 0; i < pieces.length; i++)
|
||||
programImports.add(pieces[i][1]); // the package name
|
||||
|
||||
return programImports;
|
||||
}
|
||||
|
||||
|
||||
static String substituteUnicode(String program) {
|
||||
// check for non-ascii chars (these will be/must be in unicode format)
|
||||
|
@@ -10,9 +10,9 @@ import java.io.OutputStream;
|
||||
/**
|
||||
* Handy process executor, collecting stdout into a given OutputStream
|
||||
*/
|
||||
public class ExternalProcessExecutor extends DefaultExecutor {
|
||||
public class CollectStdOutExecutor extends DefaultExecutor {
|
||||
|
||||
public ExternalProcessExecutor(final OutputStream os) {
|
||||
public CollectStdOutExecutor(final OutputStream stdout) {
|
||||
this.setStreamHandler(new ExecuteStreamHandler() {
|
||||
@Override
|
||||
public void setProcessInputStream(OutputStream outputStream) throws IOException {
|
||||
@@ -27,7 +27,7 @@ public class ExternalProcessExecutor extends DefaultExecutor {
|
||||
byte[] buf = new byte[4096];
|
||||
int bytes = -1;
|
||||
while ((bytes = inputStream.read(buf)) != -1) {
|
||||
os.write(buf, 0, bytes);
|
||||
stdout.write(buf, 0, bytes);
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,49 @@
|
||||
package processing.app.tools;
|
||||
|
||||
import org.apache.commons.exec.DefaultExecutor;
|
||||
import org.apache.commons.exec.ExecuteStreamHandler;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
|
||||
/**
|
||||
* Handy process executor, collecting stdout and stderr into given OutputStreams
|
||||
*/
|
||||
public class CollectStdOutStdErrExecutor extends DefaultExecutor {
|
||||
|
||||
public CollectStdOutStdErrExecutor(final OutputStream stdout, final OutputStream stderr) {
|
||||
this.setStreamHandler(new ExecuteStreamHandler() {
|
||||
@Override
|
||||
public void setProcessInputStream(OutputStream outputStream) throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessErrorStream(InputStream inputStream) throws IOException {
|
||||
byte[] buf = new byte[4096];
|
||||
int bytes = -1;
|
||||
while ((bytes = inputStream.read(buf)) != -1) {
|
||||
stderr.write(buf, 0, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setProcessOutputStream(InputStream inputStream) throws IOException {
|
||||
byte[] buf = new byte[4096];
|
||||
int bytes = -1;
|
||||
while ((bytes = inputStream.read(buf)) != -1) {
|
||||
stdout.write(buf, 0, bytes);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() throws IOException {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
@@ -0,0 +1,35 @@
|
||||
package processing.app.tools;
|
||||
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import processing.app.helpers.OSUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class DoubleQuotedArgumentsOnWindowsCommandLine extends CommandLine {
|
||||
|
||||
public DoubleQuotedArgumentsOnWindowsCommandLine(String executable) {
|
||||
super(executable);
|
||||
}
|
||||
|
||||
public DoubleQuotedArgumentsOnWindowsCommandLine(File executable) {
|
||||
super(executable);
|
||||
}
|
||||
|
||||
public DoubleQuotedArgumentsOnWindowsCommandLine(CommandLine other) {
|
||||
super(other);
|
||||
}
|
||||
|
||||
@Override
|
||||
public CommandLine addArgument(String argument, boolean handleQuoting) {
|
||||
// Brutal hack to workaround windows command line parsing.
|
||||
// http://stackoverflow.com/questions/5969724/java-runtime-exec-fails-to-escape-characters-properly
|
||||
// http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
|
||||
// http://bugs.sun.com/view_bug.do?bug_id=6468220
|
||||
// http://bugs.sun.com/view_bug.do?bug_id=6518827
|
||||
if (argument.contains("\"") && OSUtils.isWindows()) {
|
||||
argument = argument.replace("\"", "\\\"");
|
||||
}
|
||||
|
||||
return super.addArgument(argument, handleQuoting);
|
||||
}
|
||||
}
|
@@ -22,23 +22,21 @@
|
||||
|
||||
package processing.app.windows;
|
||||
|
||||
import com.sun.jna.Library;
|
||||
import com.sun.jna.Native;
|
||||
|
||||
import org.apache.commons.exec.CommandLine;
|
||||
import org.apache.commons.exec.Executor;
|
||||
|
||||
import processing.app.PreferencesData;
|
||||
import processing.app.debug.TargetPackage;
|
||||
import processing.app.legacy.PApplet;
|
||||
import processing.app.legacy.PConstants;
|
||||
import processing.app.tools.ExternalProcessExecutor;
|
||||
import processing.app.tools.CollectStdOutExecutor;
|
||||
import processing.app.windows.Registry.REGISTRY_ROOT_KEY;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
|
||||
@@ -55,7 +53,7 @@ public class Platform extends processing.app.Platform {
|
||||
"\\arduino.exe \"%1\"";
|
||||
static final String DOC = "Arduino.Document";
|
||||
|
||||
public void init() {
|
||||
public void init() throws IOException {
|
||||
super.init();
|
||||
|
||||
checkAssociations();
|
||||
@@ -244,7 +242,7 @@ public class Platform extends processing.app.Platform {
|
||||
// "Access is denied" in both cygwin and the "dos" prompt.
|
||||
//Runtime.getRuntime().exec("cmd /c " + currentDir + "\\reference\\" +
|
||||
// referenceFile + ".html");
|
||||
if (url.startsWith("http://")) {
|
||||
if (url.startsWith("http")) {
|
||||
// open dos prompt, give it 'start' command, which will
|
||||
// open the url properly. start by itself won't work since
|
||||
// it appears to need cmd
|
||||
@@ -281,36 +279,6 @@ public class Platform extends processing.app.Platform {
|
||||
// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
|
||||
|
||||
|
||||
// Code partially thanks to Richard Quirk from:
|
||||
// http://quirkygba.blogspot.com/2009/11/setting-environment-variables-in-java.html
|
||||
|
||||
static WinLibC clib = (WinLibC) Native.loadLibrary("msvcrt", WinLibC.class);
|
||||
|
||||
public interface WinLibC extends Library {
|
||||
//WinLibC INSTANCE = (WinLibC) Native.loadLibrary("msvcrt", WinLibC.class);
|
||||
//libc = Native.loadLibrary("msvcrt", WinLibC.class);
|
||||
public int _putenv(String name);
|
||||
}
|
||||
|
||||
|
||||
public void setenv(String variable, String value) {
|
||||
//WinLibC clib = WinLibC.INSTANCE;
|
||||
clib._putenv(variable + "=" + value);
|
||||
}
|
||||
|
||||
|
||||
public String getenv(String variable) {
|
||||
return System.getenv(variable);
|
||||
}
|
||||
|
||||
|
||||
public int unsetenv(String variable) {
|
||||
//WinLibC clib = WinLibC.INSTANCE;
|
||||
//clib._putenv(variable + "=");
|
||||
//return 0;
|
||||
return clib._putenv(variable + "=");
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return PConstants.platformNames[PConstants.WINDOWS];
|
||||
@@ -318,6 +286,7 @@ public class Platform extends processing.app.Platform {
|
||||
|
||||
@Override
|
||||
public Map<String, Object> resolveDeviceAttachedTo(String serial, Map<String, TargetPackage> packages, String devicesListOutput) {
|
||||
assert packages != null;
|
||||
if (devicesListOutput == null) {
|
||||
return super.resolveDeviceAttachedTo(serial, packages, devicesListOutput);
|
||||
}
|
||||
@@ -338,7 +307,7 @@ public class Platform extends processing.app.Platform {
|
||||
@Override
|
||||
public String preListAllCandidateDevices() {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
Executor executor = new ExternalProcessExecutor(baos);
|
||||
Executor executor = new CollectStdOutExecutor(baos);
|
||||
|
||||
try {
|
||||
String listComPorts = new File(System.getProperty("user.dir"), "hardware/tools/listComPorts.exe").getCanonicalPath();
|
||||
@@ -350,4 +319,24 @@ public class Platform extends processing.app.Platform {
|
||||
return super.preListAllCandidateDevices();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void fixPrefsFilePermissions(File prefsFile) throws IOException {
|
||||
//noop
|
||||
}
|
||||
|
||||
public List<File> postInstallScripts(File folder) {
|
||||
List<File> scripts = new LinkedList<File>();
|
||||
scripts.add(new File(folder, "post_install.bat"));
|
||||
return scripts;
|
||||
}
|
||||
|
||||
public void symlink(File something, File somewhere) throws IOException, InterruptedException {
|
||||
}
|
||||
|
||||
public void link(File something, File somewhere) throws IOException, InterruptedException {
|
||||
}
|
||||
|
||||
public void chmod(File file, int mode) throws IOException, InterruptedException {
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user