blob: 0a0d0cf2ad4a8d8299cc8753a27c7f0b3e5a5bb4 [file] [log] [blame]
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Task;
/**
* Ant Task for copying the PImage and PGraphics methods into PApplet.
*/
public class PAppletMethods extends Task {
private File baseDir;
public PAppletMethods() {
}
public void setDir(String dir) {
baseDir = new File(dir);
}
public void execute() throws BuildException {
// Do a bunch of checks...
if (baseDir == null) {
throw new BuildException("dir parameter must be set!");
}
//System.out.println("using basedir " + baseDir);
File graphicsFile = new File(baseDir, "PGraphics.java");
File appletFile = new File(baseDir, "PApplet.java");
File imageFile = new File(baseDir, "PImage.java");
if (!graphicsFile.exists() || !graphicsFile.canRead()) {
throw new BuildException("PGraphics file not readable: " +
graphicsFile.getAbsolutePath());
}
if (!appletFile.exists() ||
!appletFile.canRead() ||
!appletFile.canWrite()) {
throw new BuildException("PApplet file not read/writeable: " +
appletFile.getAbsolutePath());
}
if (!imageFile.exists() || !imageFile.canRead()) {
throw new BuildException("PImage file not readable: " +
imageFile.getAbsolutePath());
}
// Looking good, let's do this!
//ByteArrayOutputStream outBytes = new ByteArrayOutputStream();
//PrintStream out = new PrintStream(outBytes, "UTF-8");
StringBuffer out = new StringBuffer();
StringBuffer content = new StringBuffer();
try{
BufferedReader applet = createReader(appletFile);
String line;
while ((line = applet.readLine()) != null) {
out.append(line);
out.append('\n'); // to avoid Windows CRs
content.append(line);
content.append('\n'); // for efficiency
if (line.indexOf("public functions for processing.core") >= 0) {
break;
}
}
// read the rest of the file and append it to the
while ((line = applet.readLine()) != null) {
content.append(line);
content.append('\n');
}
applet.close();
process(out, graphicsFile);
process(out, imageFile);
out.append('}');
out.append('\n');
//} catch (IOException e) {
//e.printStackTrace();
} catch (Exception e) {
//ex.printStackTrace();
throw new BuildException(e);
}
//out.flush();
String outString = out.toString();
if (content.toString().equals(outString)) {
System.out.println("No changes to PApplet API.");
} else {
System.out.println("Updating PApplet with API changes " +
"from PImage or PGraphics.");
try {
PrintStream temp = new PrintStream(appletFile, "UTF-8");
temp.print(outString);
temp.flush();
temp.close();
} catch (IOException e) {
//e.printStackTrace();
throw new BuildException(e);
}
}
}
private void process(StringBuffer out, File input) throws IOException {
BufferedReader in = createReader(input);
int comments = 0;
String line = null;
StringBuffer commentBuffer = new StringBuffer();
while ((line = in.readLine()) != null) {
String decl = "";
// Keep track of comments
//if (line.matches(Pattern.quote("/*"))) {
if (line.indexOf("/*") != -1) {
comments++;
}
//if (line.matches(Pattern.quote("*/"))) {
if (line.indexOf("*/") != -1) {
commentBuffer.append(line);
commentBuffer.append('\n');
//System.out.println("comment is: " + commentBuffer.toString());
comments--;
// otherwise gotSomething will be false, and nuke the comment
continue;
}
// Ignore everything inside comments
if (comments > 0) {
commentBuffer.append(line);
commentBuffer.append('\n');
continue;
}
boolean gotSomething = false;
boolean gotStatic = false;
Matcher result;
if ((result = Pattern.compile("^\\s*public ([\\w\\[\\]]+) [a-zA-z_]+\\(.*$").matcher(line)).matches()) {
gotSomething = true;
} else if ((result = Pattern.compile("^\\s*abstract public ([\\w\\[\\]]+) [a-zA-z_]+\\(.*$").matcher(line)).matches()) {
gotSomething = true;
} else if ((result = Pattern.compile("^\\s*public final ([\\w\\[\\]]+) [a-zA-z_]+\\(.*$").matcher(line)).matches()) {
gotSomething = true;
} else if ((result = Pattern.compile("^\\s*static public ([\\w\\[\\]]+) [a-zA-z_]+\\(.*$").matcher(line)).matches()) {
gotSomething = true;
gotStatic = true;
}
// if function is marked "// ignore" then, uh, ignore it.
if (gotSomething && line.indexOf("// ignore") >= 0) {
gotSomething = false;
}
String returns = "";
if (gotSomething) {
if (result.group(1).equals("void")) {
returns = "";
} else {
returns = "return ";
}
// remove the abstract modifier
line = line.replaceFirst(Pattern.quote("abstract"), " ");
// replace semicolons with a start def
line = line.replaceAll(Pattern.quote(";"), " {\n");
//out.println("\n\n" + line);
out.append('\n');
out.append('\n');
// end has its own newline
//out.print(commentBuffer.toString()); // TODO disabled for now XXXX
out.append(commentBuffer.toString()); // duplicates all comments
commentBuffer.setLength(0);
out.append(line);
out.append('\n');
decl += line;
while(line.indexOf(')') == -1) {
line = in.readLine();
decl += line;
line = line.replaceAll("\\;\\s*$", " {\n");
out.append(line);
out.append('\n');
}
result = Pattern.compile(".*?\\s(\\S+)\\(.*?").matcher(decl);
// try to match. don't remove this or things will stop working!
result.matches();
String declName = result.group(1);
String gline = "";
String rline = "";
if (gotStatic) {
gline = " " + returns + "PGraphics." + declName + "(";
} else {
rline = " if (recorder != null) recorder." + declName + "(";
gline = " " + returns + "g." + declName + "(";
}
decl = decl.replaceAll("\\s+", " "); // smush onto a single line
decl = decl.replaceFirst("^.*\\(", "");
decl = decl.replaceFirst("\\).*$", "");
int prev = 0;
String parts[] = decl.split("\\, ");
for (String part : parts) {
if (!part.trim().equals("")) {
String blargh[] = part.split(" ");
String theArg = blargh[1].replaceAll("[\\[\\]]", "");
if (prev != 0) {
gline += ", ";
rline += ", ";
}
gline += theArg;
rline += theArg;
prev = 1;
}
}
gline += ");";
rline += ");";
if (!gotStatic && returns.equals("")) {
out.append(rline);
out.append('\n');
}
out.append(gline);
out.append('\n');
out.append(" }");
out.append('\n');
} else {
commentBuffer.setLength(0);
}
}
in.close();
}
static BufferedReader createReader(File file) throws IOException {
FileInputStream fis = new FileInputStream(file);
return new BufferedReader(new InputStreamReader(fis, "UTF-8"));
}
}