Questo programma riformatta un sorgente java in modo da renderlo pių leggibile, inoltre
č possibile eliminare i commenti dal sorgente java, estrarre le stringhe contenute nel sorgente java e trasformare il sorgente java in html. Download pretty.jar
Ecco il risultato di Pretty applicato al sorgente stesso:
/* Program pretty: used to reformat a java program in order to look better
05-11-2005 Version 0.1: initial release
05-11-2006 Version 0.2: minor changes
10-11-2007 Version 0.3: conversion to html now supported
Usage: java Pretty [-notabs] [-nocomment] [-strings] [-html] [-help] <filename> [<outfile>]
-notabs use blanks instead of tabs
-nocomment remove every comment
-strings print-out strings
-html convert java source to html, colorize java source
-help print this help message
Requires Java 1.5
javalc6
*/
import java.io.*;
import parser.*;
import java.util.ArrayList;
enum State { SOURCE, STRING, COMMENT, SHORT_COMMENT, CHAR }
interface callback {
void print(String s, State state);
void println(String s, State state);
}
publicclass Pretty {
boolean notabs, nocomment, strings, html;
PrintWriter out = null;
boolean newline;
int column;
final String blanks = new blanks().generate(1000);
String color; // used only for html
finalboolean testmode = false; // testmode, normally false
privateclass blanks {
String generate(int num) {
String result ="";
for (int i = 0; i < num; i++) result += " ";
return (result);
}
};
privateclass HandleSource implements callback {
publicvoid print(String s, State state) {
StringBuffer str = new StringBuffer();
if (s.length() == 0) return;
if ((state == State.SOURCE) && newline) {
// source in newline
String ss = removeLeadingChars(s);
if ((ss.length() > 0) && (ss.charAt(0) == '}')) column--;
if (notabs) str.append(blanks.substring(0,column*4));
elsefor (int i =0; i < column; i++)
{ str.append("\t"); }
str.append(ss);
for (int i = 0; i < ss.length(); i++) {
if (ss.charAt(i) == '{') column++;
if ((i > 0)&&(ss.charAt(i) == '}')) column--;
}
}
else {
if (!nocomment) str.append(s);
elseif (state != State.COMMENT) // comment
str.append(s);
if (state == State.SOURCE) // source
for (int i = 0; i < s.length(); i++) {
if (s.charAt(i) == '{') column++;
if (s.charAt(i) == '}') column--;
}
}
if (html) printHTML(str, state);
else out.print(str);
newline = false;
}
publicvoid println(String s, State state) {
print(s, state);
out.println();
newline = true;
}
}
Pretty (String [] files, boolean notabs, boolean nocomment, boolean strings, boolean html) {
this.notabs = notabs;
this.nocomment = nocomment;
this.strings = strings;
this.html = html;
java.util.Arrays.sort(Java.keywords);
newline = true;
column = 0;
try {
String result;
if (files.length == 2) result = files[1];
elseif (html) result = files[0]+".html";
else result = files[0]+".new";
LineNumberReader in = new LineNumberReader(new FileReader(files[0]));
long zz = System.currentTimeMillis();
out = open(result, files[0]);
syntax(in, new HandleSource());
close(out);
if (testmode) {
System.out.println("Result: "+lazyCompare(new File(files[0]), new File(result))+" Elapsed time (ms): "+(System.currentTimeMillis() - zz));
}
else System.out.println("Elapsed time (ms): "+(System.currentTimeMillis() - zz));
}
catch (IOException ex) {
System.err.println(ex.toString());
if (out != null)
out.close();
}
}
void syntax (LineNumberReader in, callback cb) throws IOException {
String s;
State state = State.SOURCE;
while ((s = in.readLine()) != null) {
int marker = 0;
main: // for each char in string
for (int i = 0; i < s.length(); i++)
{
switch (state)
{
case SOURCE : // source
if (s.startsWith("//", i))
{ cb.print(s.substring(marker, i), state); // source
marker = i;
state = State.SHORT_COMMENT; // short_comment
break main;
}
if (s.startsWith("/*", i))
{ cb.print(s.substring(marker, i), state); // source
marker = i;
state = State.COMMENT; // comment
break;
}
if (s.charAt(i) == '\"')
{ cb.print(s.substring(marker, i), state); // source
marker = i;
state = State.STRING; // string
break;
}
if (s.charAt(i) == '\'')
{ cb.print(s.substring(marker, i), state); // source
marker = i;
state = State.CHAR; // char
break;
}
break;
case STRING: // string
if (s.charAt(i) == '\"')
{ cb.print(s.substring(marker, i), state); // string
if (strings) System.out.println(s.substring(marker, i+1));
marker = i;
state = State.SOURCE; // source
}
if (s.charAt(i) == '\\') i++; // escape, skip
break;
case COMMENT: // comment
if (s.startsWith("*/", i))
{ cb.print(s.substring(marker, i+2), state); // comment
marker = i+2;
state = State.SOURCE; // source
} // else if (s.indexOf("*/", i) == -1) break main;
break;
case SHORT_COMMENT: // short_comment
thrownew RuntimeException("Assert failed");
case CHAR: // char
if (s.charAt(i) == '\'')
{ cb.print(s.substring(marker, i), State.STRING); // string ???
marker = i;
state = State.SOURCE; // source
}
if (s.charAt(i) == '\\') i++; // escape, skip
break;
}
}
// all chars in the current line were analysed
switch (state)
{
case SOURCE : // source
cb.println(s.substring(marker), state); // source
break;
case STRING: // string
thrownew IOException("Wrong syntax: string not terminated correctly at line "+in.getLineNumber());
case COMMENT: // comment
cb.println(s.substring(marker), state); // comment
break;
case SHORT_COMMENT: // short_comment
cb.println(s.substring(marker), State.COMMENT); // comment (even if it is short...)
state = State.SOURCE; // source
break;
case CHAR: // char
thrownew IOException("Wrong syntax: char not terminated correctly at line "+in.getLineNumber());
}
// main while
}
in.close();
}
String removeLeadingChars(String line) {
int i=0;
while ((i < line.length())&&((line.charAt(i) == ' ')||(line.charAt(i) == '\t'))) i++;
return (line.substring(i));
}
PrintWriter open(String filename, String source) throws IOException {
PrintWriter out = new PrintWriter(new FileWriter(new File(filename)));
if (html) {
out.println();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<html>");
out.println("<head>");
out.println("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=windows-1252\">");
out.println("<meta name=\"description\" content=\"Programmi Java\">");
out.println("<title>"+encodeHTML(new StringBuffer(source))+"</title>");
out.println("</head>");
out.println("<body><pre><font color=\"#000000\">");
color = "#000000"; // used only for html
}
return out;
}
void close(PrintWriter out) {
if (html) {
out.println("</font></pre></body>");
out.println("</html>");
}
out.close();
}
boolean testAlfa(char ch) {
return ((ch >= 'a')&&(ch <= 'z'))||((ch >= 'A')&&(ch <= 'Z'));
}
boolean testDigit(char ch) {
return ((ch >= '0')&&(ch <= '9'));
}
void printHTML(StringBuffer str, State state) {
String oldcolor = color;
switch (state) {
case SOURCE : color = "#000000";
break;
case COMMENT : color = "#339966";
break;
default: color = "#0033CC";
}
if (!color.equals(oldcolor)) {
out.print("</font><font color=\""+color+"\">");
}
if (state == State.SOURCE) {
int i = 0;
while (i < str.length()) {
// skips blank and tabs
char ch = str.charAt(i);
if (testAlfa(ch)||(ch == '_')||(ch == '$')) {
StringBuffer id = new StringBuffer();
do {
id.append(ch);
i++;
if (i >= str.length()) break;
ch = str.charAt(i);
}
while (testAlfa(ch)||(ch == '_')||(ch == '$') || testDigit(ch));
if (java.util.Arrays.binarySearch(Java.keywords, id.toString()) >= 0)
out.print("<b>"+encodeHTML(id)+"</b>");
else out.print(encodeHTML(id));
}
if (i >= str.length()) break;
out.print(encodeHTML(new StringBuffer(str.substring(i,i+1))));
i++;
}
} else out.print(encodeHTML(str));
}
public StringBuffer encodeHTML(StringBuffer s) {
StringBuffer out = new StringBuffer();
for(int i=0; i<s.length(); i++)
{
char c = s.charAt(i);
if(c > 127 || c=='"' || c=='<' || c=='>') {
out.append("&#"+(int)c+";");
}
elseif (c=='"') out.append(""");
elseif (c=='<') out.append("<");
elseif (c=='>') out.append(">");
elseif (c=='&') out.append("&");
else {
out.append(c);
}
}
return out;
}
publicstaticboolean lazyCompare(File file1, File file2) throws IOException {
InputStream bufferedInput1 = new BufferedInputStream(new java.io.FileInputStream(file1));
InputStream bufferedInput2 = new BufferedInputStream(new java.io.FileInputStream(file2));
int ch = bufferedInput1.read();
int ch2 = bufferedInput2.read();
while(true) {
while ((-1 != ch)&&(" \t\n\r".indexOf(ch) != -1)) {
ch = bufferedInput1.read();
}
while ((-1 != ch2)&&(" \t\n\r".indexOf(ch2) != -1)) {
ch2 = bufferedInput2.read();
}
if (ch == -1) return -1 == ch2;
// System.err.println(ch+"<->"+ch2);
if( ch != ch2 ) return false;
ch = bufferedInput1.read();
ch2 = bufferedInput2.read();
}
}
//main
publicstaticvoid main(String[] args) throws ParserException
{
Parser cli = new Parser();
Option notabs = cli.addOption("-notabs", false, null,"use blanks instead of tabs");
Option nocomment = cli.addOption("-nocomment", false, null,"remove every comment");
Option strings = cli.addOption("-strings", false, null,"print-out strings");
Option html = cli.addOption("-html", false, null,"convert java to html");
cli.addOption("-help", false, null,"print this help message");
String [] result = cli.parse(args);
if ((result.length > 0)&&(result.length < 3)) {
if (new File(result[0]).isDirectory()) System.err.println("Error: "+result[0]+" is a directory!");
elsenew Pretty(result, cli.hasOption(notabs), cli.hasOption(nocomment), cli.hasOption(strings), cli.hasOption(html));
}
else System.err.println("Usage: java Pretty"+cli.getUsage("<filename> [<outfile>]"));
}
}