Java browser: Pretty.java

Content of Pretty.java extracted from pretty.jar

/* 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);
}
 
public class 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
 
 
	final boolean testmode = false; // testmode, normally false
 
 
	private class blanks {
		String generate(int num) {
			String result ="";
			for (int i = 0; i < num; i++) result += " ";
			return (result);
		}
	};
 
	private class HandleSource implements callback {
		public void 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));
				else for (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);
				else if (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;
		}
		public void 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];
			else	if (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
						throw new 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
					throw new 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
					throw new 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+";");
			}
			else if (c=='"') out.append("&quot;");
			else if (c=='<') out.append("&lt;");
			else if (c=='>') out.append("&gt;");
			else if (c=='&') out.append("&amp;");
			else {
				out.append(c);
			}
		}
		return out;
	}
 
	public static boolean 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	
	public static void 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!");
			else new 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>]"));
	}
}
 
Share Share on Facebook Share on Twitter Bookmark on Reddit Share via mail
Privacy Policy Creative Commons Attribution-Share Alike Trovami