mirror of
https://github.com/arduino/Arduino.git
synced 2024-12-11 22:24:13 +01:00
301 lines
11 KiB
Plaintext
301 lines
11 KiB
Plaintext
/*
|
|
// make sure the user didn't hide the sketch folder
|
|
ensureExistence();
|
|
|
|
zipFileContents = new Hashtable();
|
|
|
|
// nuke the old applet folder because it can cause trouble
|
|
File appletFolder = new File(folder, "applet");
|
|
Base.removeDir(appletFolder);
|
|
appletFolder.mkdirs();
|
|
|
|
// build the sketch
|
|
String foundName = build(appletFolder.getPath(), name);
|
|
|
|
// (already reported) error during export, exit this function
|
|
if (foundName == null) return false;
|
|
|
|
// if name != exportSketchName, then that's weirdness
|
|
// BUG unfortunately, that can also be a bug in the preproc :(
|
|
if (!name.equals(foundName)) {
|
|
Base.showWarning("Error during export",
|
|
"Sketch name is " + name + " but the sketch\n" +
|
|
"name in the code was " + foundName, null);
|
|
return false;
|
|
}
|
|
|
|
int wide = PApplet.DEFAULT_WIDTH;
|
|
int high = PApplet.DEFAULT_HEIGHT;
|
|
|
|
PatternMatcher matcher = new Perl5Matcher();
|
|
PatternCompiler compiler = new Perl5Compiler();
|
|
|
|
// this matches against any uses of the size() function,
|
|
// whether they contain numbers of variables or whatever.
|
|
// this way, no warning is shown if size() isn't actually
|
|
// used in the applet, which is the case especially for
|
|
// beginners that are cutting/pasting from the reference.
|
|
// modified for 83 to match size(XXX, ddd so that it'll
|
|
// properly handle size(200, 200) and size(200, 200, P3D)
|
|
String sizing =
|
|
"[\\s\\;]size\\s*\\(\\s*(\\S+)\\s*,\\s*(\\d+)";
|
|
Pattern pattern = compiler.compile(sizing);
|
|
|
|
// adds a space at the beginning, in case size() is the very
|
|
// first thing in the program (very common), since the regexp
|
|
// needs to check for things in front of it.
|
|
PatternMatcherInput input =
|
|
new PatternMatcherInput(" " + code[0].program);
|
|
if (matcher.contains(input, pattern)) {
|
|
MatchResult result = matcher.getMatch();
|
|
try {
|
|
wide = Integer.parseInt(result.group(1).toString());
|
|
high = Integer.parseInt(result.group(2).toString());
|
|
|
|
} catch (NumberFormatException e) {
|
|
// found a reference to size, but it didn't
|
|
// seem to contain numbers
|
|
final String message =
|
|
"The size of this applet could not automatically be\n" +
|
|
"determined from your code. You'll have to edit the\n" +
|
|
"HTML file to set the size of the applet.";
|
|
|
|
Base.showWarning("Could not find applet size", message, null);
|
|
}
|
|
} // else no size() command found
|
|
|
|
// originally tried to grab this with a regexp matcher,
|
|
// but it wouldn't span over multiple lines for the match.
|
|
// this could prolly be forced, but since that's the case
|
|
// better just to parse by hand.
|
|
StringBuffer dbuffer = new StringBuffer();
|
|
String lines[] = PApplet.split(code[0].program, '\n');
|
|
for (int i = 0; i < lines.length; i++) {
|
|
if (lines[i].trim().startsWith("/**")) { // this is our comment
|
|
// some smartass put the whole thing on the same line
|
|
//if (lines[j].indexOf("*/") != -1) break;
|
|
|
|
for (int j = i+1; j < lines.length; j++) {
|
|
if (lines[j].trim().endsWith("*/")) {
|
|
// remove the */ from the end, and any extra *s
|
|
// in case there's also content on this line
|
|
// nah, don't bother.. make them use the three lines
|
|
break;
|
|
}
|
|
|
|
int offset = 0;
|
|
while ((offset < lines[j].length()) &&
|
|
((lines[j].charAt(offset) == '*') ||
|
|
(lines[j].charAt(offset) == ' '))) {
|
|
offset++;
|
|
}
|
|
// insert the return into the html to help w/ line breaks
|
|
dbuffer.append(lines[j].substring(offset) + "\n");
|
|
}
|
|
}
|
|
}
|
|
String description = dbuffer.toString();
|
|
|
|
StringBuffer sources = new StringBuffer();
|
|
for (int i = 0; i < codeCount; i++) {
|
|
sources.append("<a href=\"" + code[i].file.getName() + "\">" +
|
|
code[i].name + "</a> ");
|
|
}
|
|
|
|
File htmlOutputFile = new File(appletFolder, "index.html");
|
|
FileOutputStream fos = new FileOutputStream(htmlOutputFile);
|
|
PrintStream ps = new PrintStream(fos);
|
|
|
|
// @@sketch@@, @@width@@, @@height@@, @@archive@@, @@source@@
|
|
// and now @@description@@
|
|
|
|
InputStream is = null;
|
|
// if there is an applet.html file in the sketch folder, use that
|
|
File customHtml = new File(folder, "applet.html");
|
|
if (customHtml.exists()) {
|
|
is = new FileInputStream(customHtml);
|
|
}
|
|
if (is == null) {
|
|
is = Base.getStream("applet.html");
|
|
}
|
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
|
|
|
String line = null;
|
|
while ((line = reader.readLine()) != null) {
|
|
if (line.indexOf("@@") != -1) {
|
|
StringBuffer sb = new StringBuffer(line);
|
|
int index = 0;
|
|
while ((index = sb.indexOf("@@sketch@@")) != -1) {
|
|
sb.replace(index, index + "@@sketch@@".length(),
|
|
name);
|
|
}
|
|
while ((index = sb.indexOf("@@source@@")) != -1) {
|
|
sb.replace(index, index + "@@source@@".length(),
|
|
sources.toString());
|
|
}
|
|
while ((index = sb.indexOf("@@archive@@")) != -1) {
|
|
sb.replace(index, index + "@@archive@@".length(),
|
|
name + ".jar");
|
|
}
|
|
while ((index = sb.indexOf("@@width@@")) != -1) {
|
|
sb.replace(index, index + "@@width@@".length(),
|
|
String.valueOf(wide));
|
|
}
|
|
while ((index = sb.indexOf("@@height@@")) != -1) {
|
|
sb.replace(index, index + "@@height@@".length(),
|
|
String.valueOf(high));
|
|
}
|
|
while ((index = sb.indexOf("@@description@@")) != -1) {
|
|
sb.replace(index, index + "@@description@@".length(),
|
|
description);
|
|
}
|
|
line = sb.toString();
|
|
}
|
|
ps.println(line);
|
|
}
|
|
|
|
reader.close();
|
|
ps.flush();
|
|
ps.close();
|
|
|
|
// copy the loading gif to the applet
|
|
String LOADING_IMAGE = "loading.gif";
|
|
File loadingImage = new File(folder, LOADING_IMAGE);
|
|
if (!loadingImage.exists()) {
|
|
loadingImage = new File("lib", LOADING_IMAGE);
|
|
}
|
|
Base.copyFile(loadingImage, new File(appletFolder, LOADING_IMAGE));
|
|
|
|
// copy the source files to the target, since we like
|
|
// to encourage people to share their code
|
|
for (int i = 0; i < codeCount; i++) {
|
|
try {
|
|
Base.copyFile(code[i].file,
|
|
new File(appletFolder, code[i].file.getName()));
|
|
} catch (IOException e) {
|
|
e.printStackTrace();
|
|
}
|
|
}
|
|
|
|
// create new .jar file
|
|
FileOutputStream zipOutputFile =
|
|
new FileOutputStream(new File(appletFolder, name + ".jar"));
|
|
ZipOutputStream zos = new ZipOutputStream(zipOutputFile);
|
|
ZipEntry entry;
|
|
|
|
// add the manifest file
|
|
addManifest(zos);
|
|
|
|
// add the contents of the code folder to the jar
|
|
// unpacks all jar files
|
|
//File codeFolder = new File(folder, "code");
|
|
if (codeFolder.exists()) {
|
|
String includes = Compiler.contentsToClassPath(codeFolder);
|
|
packClassPathIntoZipFile(includes, zos);
|
|
}
|
|
|
|
// add contents of 'library' folders to the jar file
|
|
// if a file called 'export.txt' is in there, it contains
|
|
// a list of the files that should be exported.
|
|
// otherwise, all files are exported.
|
|
Enumeration en = importedLibraries.elements();
|
|
while (en.hasMoreElements()) {
|
|
// in the list is a File object that points the
|
|
// library sketch's "library" folder
|
|
File libraryFolder = (File)en.nextElement();
|
|
File exportSettings = new File(libraryFolder, "export.txt");
|
|
String exportList[] = null;
|
|
if (exportSettings.exists()) {
|
|
String info[] = Base.loadStrings(exportSettings);
|
|
for (int i = 0; i < info.length; i++) {
|
|
if (info[i].startsWith("applet")) {
|
|
int idx = info[i].indexOf('='); // get applet= or applet =
|
|
String commas = info[i].substring(idx+1).trim();
|
|
exportList = PApplet.split(commas, ", ");
|
|
}
|
|
}
|
|
} else {
|
|
exportList = libraryFolder.list();
|
|
}
|
|
for (int i = 0; i < exportList.length; i++) {
|
|
if (exportList[i].equals(".") ||
|
|
exportList[i].equals("..")) continue;
|
|
|
|
exportList[i] = PApplet.trim(exportList[i]);
|
|
if (exportList[i].equals("")) continue;
|
|
|
|
File exportFile = new File(libraryFolder, exportList[i]);
|
|
if (!exportFile.exists()) {
|
|
System.err.println("File " + exportList[i] + " does not exist");
|
|
|
|
} else if (exportFile.isDirectory()) {
|
|
System.err.println("Ignoring sub-folder \"" + exportList[i] + "\"");
|
|
|
|
} else if (exportFile.getName().toLowerCase().endsWith(".zip") ||
|
|
exportFile.getName().toLowerCase().endsWith(".jar")) {
|
|
packClassPathIntoZipFile(exportFile.getAbsolutePath(), zos);
|
|
|
|
} else { // just copy the file over.. prolly a .dll or something
|
|
Base.copyFile(exportFile,
|
|
new File(appletFolder, exportFile.getName()));
|
|
}
|
|
}
|
|
}
|
|
|
|
String bagelJar = "lib/core.jar";
|
|
packClassPathIntoZipFile(bagelJar, zos);
|
|
|
|
// files to include from data directory
|
|
// TODO this needs to be recursive
|
|
if (dataFolder.exists()) {
|
|
String dataFiles[] = dataFolder.list();
|
|
for (int i = 0; i < dataFiles.length; i++) {
|
|
// don't export hidden files
|
|
// skipping dot prefix removes all: . .. .DS_Store
|
|
if (dataFiles[i].charAt(0) == '.') continue;
|
|
|
|
entry = new ZipEntry(dataFiles[i]);
|
|
zos.putNextEntry(entry);
|
|
zos.write(Base.grabFile(new File(dataFolder, dataFiles[i])));
|
|
zos.closeEntry();
|
|
}
|
|
}
|
|
|
|
// add the project's .class files to the jar
|
|
// just grabs everything from the build directory
|
|
// since there may be some inner classes
|
|
// (add any .class files from the applet dir, then delete them)
|
|
// TODO this needs to be recursive (for packages)
|
|
String classfiles[] = appletFolder.list();
|
|
for (int i = 0; i < classfiles.length; i++) {
|
|
if (classfiles[i].endsWith(".class")) {
|
|
entry = new ZipEntry(classfiles[i]);
|
|
zos.putNextEntry(entry);
|
|
zos.write(Base.grabFile(new File(appletFolder, classfiles[i])));
|
|
zos.closeEntry();
|
|
}
|
|
}
|
|
|
|
// remove the .class files from the applet folder. if they're not
|
|
// removed, the msjvm will complain about an illegal access error,
|
|
// since the classes are outside the jar file.
|
|
for (int i = 0; i < classfiles.length; i++) {
|
|
if (classfiles[i].endsWith(".class")) {
|
|
File deadguy = new File(appletFolder, classfiles[i]);
|
|
if (!deadguy.delete()) {
|
|
Base.showWarning("Could not delete",
|
|
classfiles[i] + " could not \n" +
|
|
"be deleted from the applet folder. \n" +
|
|
"You'll need to remove it by hand.", null);
|
|
}
|
|
}
|
|
}
|
|
|
|
// close up the jar file
|
|
zos.flush();
|
|
zos.close();
|
|
|
|
Base.openFolder(appletFolder);
|
|
return true;
|
|
*/
|