|
What this is
Other links
The source code
/*
* Copyright (c) 1998 Tal Davidson. All rights reserved.
*
* JSFormatter 0.4.0
* by Tal Davidson (davidsont@bigfoot.com)
*
* JSFormatter 0.4.0 is distributed under the "Artistic Licence" detailed below:
*
*
* The ``Artistic License''
*
* Preamble
* The intent of this document is to state the conditions under which a Package may
* be copied, such that the Copyright Holder maintains some semblance of artistic
* control over the development of the package, while giving the users of the
* package the right to use and distribute the Package in a more-or-less customary
* fashion, plus the right to make reasonable modifications.
*
* Definitions
* ``Package'' refers to the collection of files distributed by the Copyright
* Holder, and derivatives of that collection of files created through textual
* modification.
* ``Standard Version'' refers to such a Package if it has not been modified,
* or has been modified in accordance with the wishes of the Copyright Holder
* as specified below.
* ``Copyright Holder'' is whoever is named in the copyright or copyrights for
* the package.
* ``You'' is you, if you're thinking about copying or distributing this
* Package.
* ``Reasonable copying fee'' is whatever you can justify on the basis of media
* cost, duplication charges, time of people involved, and so on. (You will not
* be required to justify it to the Copyright Holder, but only to the computing
* community at large as a market that must bear the fee.)
* ``Freely Available'' means that no fee is charged for the item itself,
* though there may be fees involved in handling the item. It also means that
* recipients of the item may redistribute it under the same conditions they
* received it.
*
* 1. You may make and give away verbatim copies of the source form of the
* Standard Version of this Package without restriction, provided that you
* duplicate all of the original copyright notices and associated disclaimers.
* 2. You may apply bug fixes, portability fixes and other modifications derived
* from the Public Domain or from the Copyright Holder. A Package modified in
* such a way shall still be considered the Standard Version.
* 3. You may otherwise modify your copy of this Package in any way, provided that
* you insert a prominent notice in each changed file stating how and when you
* changed that file, and provided that you do at least ONE of the following:
* a. place your modifications in the Public Domain or otherwise make them
* Freely Available, such as by posting said modifications to Usenet or an
* equivalent medium, or placing the modifications on a major archive site
* such as uunet.uu.net, or by allowing the Copyright Holder to include
* your modifications in the Standard Version of the Package.
* b. use the modified Package only within your corporation or organization.
* c. rename any non-standard executables so the names do not conflict with
* standard executables, which must also be provided, and provide a
* separate manual page for each non-standard executable that clearly
* documents how it differs from the Standard Version.
* d. make other distribution arrangements with the Copyright Holder.
* 4. You may distribute the programs of this Package in object code or executable
* form, provided that you do at least ONE of the following:
* a. distribute a Standard Version of the executables and library files,
* together with instructions (in the manual page or equivalent) on where
* to get the Standard Version.
* b. accompany the distribution with the machine-readable source of the
* Package with your modifications.
* c. give non-standard executables non-standard names, and clearly document
* the differences in manual pages (or equivalent), together with
* instructions on where to get the Standard Version.
* d. make other distribution arrangements with the Copyright Holder.
* 5. You may charge a reasonable copying fee for any distribution of this
* Package. You may charge any fee you choose for support of this Package. You
* may not charge a fee for this Package itself. However, you may distribute
* this Package in aggregate with other (possibly commercial) programs as part
* of a larger (possibly commercial) software distribution provided that you do
* not advertise this Package as a product of your own. You may embed this
* Package's interpreter within an executable of yours (by linking); this shall
* be construed as a mere form of aggregation, provided that the complete
* Standard Version of the interpreter is so embedded.
* 6. The scripts and library files supplied as input to or produced as output
* from the programs of this Package do not automatically fall under the
* copyright of this Package, but belong to whomever generated them, and may be
* sold commercially, and may be aggregated with this Package. If such scripts
* or library files are aggregated with this Package via the so-called "undump"
* or "unexec" methods of producing a binary executable image, then
* distribution of such an image shall neither be construed as a distribution
* of this Package nor shall it fall under the restrictions of Paragraphs 3 and
* 4, provided that you do not represent such an executable image as a Standard
* Version of this Package.
* 7. C subroutines (or comparably compiled subroutines in other languages)
* supplied by you and linked into this Package in order to emulate subroutines
* and variables of the language defined by this Package shall not be
* considered part of this Package, but are the equivalent of input as in
* Paragraph 6, provided these subroutines do not change the language in any
* way that would cause it to fail the regression tests for the language.
* 8. Aggregation of this Package with a commercial distribution is always
* permitted provided that the use of this Package is embedded; that is, when
* no overt attempt is made to make this Package's interfaces visible to the
* end user of the commercial distribution. Such use shall not be construed as
* a distribution of this Package.
* 9. The name of the Copyright Holder may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
* THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
* MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
* The End
*/
import java.util.*;
import java.io.*;
public class JSFormatter {
// headers[] - an array of headers that require indentation
private static String headers[] = {"if", "else", "for", "while", "do",
"try", "catch", "synchronized", "switch", "static"};
// parenHeaders[] - an array of the headers that require parenthesies after them, i.e. while (...)
private static String parenHeaders[] = {"if", "for", "while", "catch",
"synchronized", "switch"};
private static String nonParenHeaders[] = {"else", "do", "try", "static"};
private static String statementHeaders[] = {"class", "interface", "throws"};
private static String longOperators[] = {"==", "!=", ">=", "<=", "+=",
"-=", "*=", "/=", "%=", "^=", "|=", "&=", "++", "--", "&&", "||", ".*" };
private static Hashtable closingHeaders;
static {
closingHeaders = new Hashtable();
closingHeaders.put("if", "else");
closingHeaders.put("do", "while");
closingHeaders.put("try", "catch");
}
public JSBeautifier beautifier;
private JSLineBreaker lineBreaker;
private StringBuffer outBuffer; // current parsed-line buffer
private String tempLine = ""; // parts of previous line that haven't been parsed yet
private Stack openingStack;
private Stack parenDepthsStack;
private Stack bracketBlockStateStack;
private char quoteChar;
private int parenDepth;
private int leadingWhiteSpaces;
private String currentHeader;
private boolean isInHeader;
private boolean isSpecialChar; // true if a char of type '\X' (i.e. '\n'...)
private boolean isInQuote; // true if in quote
private boolean isInComment; // true if in /**/ comment
private boolean isBlockNeeded; // ---not currently used.
private boolean isSpecialBlock; // ---not currently used.
private boolean isCloseSpecialBlock; // ---not currently used.
private boolean isParenNeeded; // true if a parenthesis statement is expected (i.e. right after a 'while' header...)
private boolean isNewLineNeeded; // true if current formatted line has reached its end.
private boolean checkBlockOpen; // hint for checking if a '{' has been reached
private boolean checkBlockClose; // hint for checking if a '}' has been reached
private boolean checkIf;
private boolean checkClosingHeader;
private boolean foundOrigLineBreak;
private boolean isInQuestion;
private boolean isSummarized;
private boolean isInBracketOpen;
private boolean isInBracketClose;
private boolean isInClassStatement;
private boolean bracketBreak = false;
private char prevNonSpaceCh;
private char currentNonSpaceCh;
public static void main(String args[]) {
JSFormatter formatter = new JSFormatter();
Vector fileNameVector = new Vector();
BufferedReader inReader = null;
PrintWriter outWriter = null;
boolean isHelpShown = false;
for (int i = 0; i < args.length; i++) {
String arg = args[i];
if (arg.equals("-b"))
formatter.setBracketBreak(true);
else if ("-ib".equals(arg)) {
formatter.setBracketBreak(true);
formatter.setBracketIndent(true);
} else if ("-fs".equals(arg))
formatter.setSwitchIndent(false);
else if (arg.startsWith("-ll")) {
int length = 70;
try {
length = Integer.valueOf(arg.substring(3)).intValue();
} catch (NumberFormatException e) {};
formatter.setPreferredLineLength(length);
} else if (arg.startsWith("-ld")) {
int dev = 5;
try {
dev = Integer.valueOf(arg.substring(3)).intValue();
} catch (NumberFormatException e) {};
formatter.setLineLengthDeviation(dev);
} else if (arg.equals("-nn")) {
formatter.setNestedConnection(false);
} else if (arg.startsWith("-") && !isHelpShown) {
isHelpShown = true;
System.err.println("");
System.err.println("Usage : java jstyle.JSFormatter [options] < Original.java > Formatted.java");
System.err.println(" java jstyle.JSFormatter [options] Foo.java Bar.java [...]");
System.err.println("");
System.err.println("When given a specific file, JSFormatter will create an output file with a");
System.err.println("suffix of \".js\" added to the original filename, i.e: Foo.java --> Foo.java.js");
System.err.println("");
System.err.println("Options: -ll# Set preferred line length to #");
System.err.println(" -ld# Set preferred upper line length deviation to #");
System.err.println(" -b Break lines BEFORE '{' brackets (ala C++ style)");
System.err.println(" -ib Same as '-b', but add extra indentation to brackets");
System.err.println(" -fs flush (i.e. don't indent) 'switch' blocks");
System.err.println(" -h Print this help message");
System.err.println();
System.exit(0);
} else
fileNameVector.addElement(arg);
}
if (fileNameVector.isEmpty()) {
inReader = new BufferedReader(new InputStreamReader(System.in));
outWriter = new PrintWriter(System.out);
try {
formatter.format(inReader, outWriter);
} catch (IOException e) {
e.printStackTrace();
}
try {
inReader.close();
} catch (IOException e) {
e.printStackTrace();
}
outWriter.close();
} else {
for (int i = 0; i < fileNameVector.size(); i++) {
try {
String fileName = (String) fileNameVector.elementAt(i);
inReader = new BufferedReader(new FileReader(fileName));
outWriter =
new PrintWriter(new FileWriter(fileName + ".js"), true);
formatter.format(inReader, outWriter);
} catch (IOException e) {
e.printStackTrace();
}
outWriter.close();
try {
inReader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
/**
* Constructor for JSFormatter
*/
public JSFormatter() {
beautifier = new JSBeautifier();
lineBreaker = new JSLineBreaker();
init();
}
/**
* Initialize the formatter so that it is ready for the formation
* of a new file of source code.
*/
public void init() {
beautifier.init();
lineBreaker.init();
outBuffer = new StringBuffer();
openingStack = new Stack();
parenDepthsStack = new Stack();
bracketBlockStateStack = new Stack();
bracketBlockStateStack.push(new Boolean(true));
tempLine = "";
parenDepth = 0;
isSpecialChar = false;
isInQuote = false;
isInComment = false;
isBlockNeeded = false;
isParenNeeded = false;
isSpecialBlock = false;
isCloseSpecialBlock = false;
isNewLineNeeded = false;
checkIf = false;
checkBlockOpen = false;
checkClosingHeader = false;
checkBlockClose = false;
foundOrigLineBreak = false;
isInQuestion = false;
isSummarized = false;
isInBracketOpen = false;
isInBracketClose = false;
leadingWhiteSpaces = 0;
isInHeader = false;
isInClassStatement = false;
prevNonSpaceCh = '{';
currentNonSpaceCh = '{';
}
/**
* Format source code that is read from inReader, and print the
* formatted result to outWriter.
*
* @param inReader a BufferedReader from which to input original source code
* @param outWriter a PrintWriter to output beutified source code to
*
* @exception IOException
*/
public void format(BufferedReader inReader,
PrintWriter outWriter) throws IOException {
String line = null;
init();
try {
while (true) {
while (!hasMoreFormattedLines()) {
line = inReader.readLine();
if (line == null)
throw new NullPointerException();
formatLine(line);
}
while (hasMoreFormattedLines())
outWriter.println(nextFormattedLine());
}
} catch (NullPointerException e) {}
summarize();
while (hasMoreFormattedLines())
outWriter.println(nextFormattedLine());
}
/**
* Check if the formatter has more formatted lines to return.
*
* As long as there are more formatted lines to return, the
* caller should NOT call the method formatLine() with a new
* line of source code, but rather collect the current available
* formatted lines with the method nextFormattedLine(), i.e:
*
* while (formatter.hasMoreFormattedLines())
* System.out.println(formatter.nextFormattedLine()
*/
public boolean hasMoreFormattedLines() {
if (lineBreaker.hasMoreBrokenLines())
return true;
else
while ((!isSummarized && !isNewLineRequested()) ||
(isSummarized && hasMoreSummarizedLines())) {
String formatResult = format(null);
if (formatResult != null) {
lineBreaker.breakLine(formatResult);
return true;
}
}
return false;
}
/**
* format a line of source code. formatLine should NOT be called
* if there are still formatted lines ready to be collected.
* This can be checked with the method hasMoreFormattedLines()
*
* @param line a line of source code to be formatted.
*/
public void formatLine(String line) {
String formatResult = format(line);
if (formatResult != null)
lineBreaker.breakLine(formatResult);
}
/**
* Get the next formatted line. This should be called ONLY after
* checking with the method hasMoreFormattedLines() that there
* actualy is a formatted line ready to be collected.
*/
public String nextFormattedLine() {
return lineBreaker.nextBrokenLine();
}
/**
* summarize() is to be called when there are no more lines
* of unformatted source code to be passed to the formatter.
*/
public void summarize() {
formatLine("");
isSummarized = true;
}
public void setBracketBreak(boolean br) {
bracketBreak = br;
}
public void setBracketIndent(boolean state) {
beautifier.setBracketIndent(state);
}
public void setSwitchIndent(boolean state) {
beautifier.setSwitchIndent(state);
}
public void setPreferredLineLength(int length) {
lineBreaker.setPreferredLineLength(length);
}
public void setLineLengthDeviation(int dev) {
lineBreaker.setLineLengthDeviation(dev);
}
public void setNestedConnection(boolean nest) {
lineBreaker.setNestedConnection(nest);
}
/*
* Does the formatter request a new line?
* This should be checked only if we have a new line to
* actually give the formatter via the format(line) method.
*/
private boolean isNewLineRequested() {
return (tempLine.indexOf("//") == -1 &&
tempLine.indexOf("/*") == -1 && tempLine.indexOf("*/") == -1);
}
/*
* Does formatter have more formatted lines in its belly?
* This should be called only after there are no more original
* lines to send the formatter.
* Until false, the new formatted lines can be retreived by
* calling the format method with an empty string, i.e. format("");
*/
private boolean hasMoreSummarizedLines() {
return !((tempLine.length() == 0) ||
(tempLine.length() == 2 && tempLine.charAt(0) == '\r' &&
tempLine.charAt(1) == '\n'));
}
/*
* Format the original line sent.
* Actually, the returned String is the next parsed line that is ready,
* and may be a part of a formerly sent original line
*/
public String format(String line) {
boolean isLineComment = false; // true when the current character is in a // comment (such as this line ...)
char ch = ' '; // the current character
char prevCh = ' ';
String outString = null;
int i;
boolean shouldPublish = false;
boolean isBreakCalled = false;
currentHeader = null;
// connect new unparsed line to former unparsed line.
if (line == null)
line = "";
else {
// remove the white-space around the current line
if (!isInComment) {
leadingWhiteSpaces = 0;
while (leadingWhiteSpaces < line.length() &&
(line.charAt(leadingWhiteSpaces) == ' ' ||
line.charAt(leadingWhiteSpaces) == '\t'))
leadingWhiteSpaces++;
line = line.trim();
} else {
int trimSize;
for (trimSize = 0; trimSize < line.length() &&
trimSize < leadingWhiteSpaces &&
(line.charAt(trimSize) == ' ' ||
line.charAt(trimSize) == '\t'); trimSize++)
;
line = line.substring(trimSize);
}
//line = line.trim();
if ("".equals(line))
line = "\n";
}
line = tempLine + " \r" + line;
// parse characters in the current line.
for (i = 0; i < line.length(); i++) {
prevCh = ch;
ch = line.charAt(i);
//shouldPublish = false;
if (!isInComment && !isLineComment && ch == '\t')
ch = ' ';
// '\n' exists when an empty line has been sent
if (ch == '\n') {
/*if (checkClosingHeader)
{
isDoubleBreak = true;
//checkClosingHeader = false;
}
*/
//if (foundOrigLineBreak)
// foundOrigLineBreak = false;
isBreakCalled = true;
break;
}
// '\r' exists at the connection points between original lines
if (ch == '\r') {
//System.out.println("found \\r at:" + i +" out of " + line.length());
ch = ' ';
if (isBreakCalled)
break;
else if (checkBlockClose) {
checkBlockClose = false;
isBreakCalled = true;
break;
} else {
foundOrigLineBreak = true;
continue;
}
}
if (ch != ' ' && ch != '\t' && !isInComment && !isLineComment &&
!isInQuote && !line.regionMatches(false, i, "//", 0, 2) &&
!line.regionMatches(false, i, "/*", 0, 2)) {
prevNonSpaceCh = currentNonSpaceCh;
currentNonSpaceCh = ch;
}
// minimize white-space
// and remove spaces that come right after parenthesies...
if (!isInComment && !isLineComment && !isInQuote && ch == ' ') {
if (currentNonSpaceCh != '(' && currentNonSpaceCh != ')' &&
currentNonSpaceCh != '[' && currentNonSpaceCh != ']')
appendSpace(outBuffer);
continue;
}
//if (!isInComment && !isInQuote && (ch == ' ' || ch == '\t'))
//{
// if (prevCh != ' ' && prevCh != '\t')
// outBuffer.append(ch);
// continue;
//}
shouldPublish = false; // called specifically AFTER white space is treated.
if (checkBlockClose) {
checkBlockClose = false;
if (ch != '}')
isBreakCalled = true;
}
// handle comments
if (!isInQuote && !(isInComment || isLineComment) &&
line.regionMatches(false, i, "//", 0, 2)) {
if (foundOrigLineBreak) {
foundOrigLineBreak = false;
if (checkClosingHeader) {
checkClosingHeader = false;
i--;
isBreakCalled = true;
break;
}
}
isLineComment = true;
checkClosingHeader = false;
outBuffer.append("//");
i++;
continue;
} else if (!isInQuote && !(isInComment || isLineComment) &&
line.regionMatches(false, i, "/*", 0, 2)) {
if (foundOrigLineBreak) {
foundOrigLineBreak = false;
if (checkClosingHeader) {
checkClosingHeader = false;
i--;
isBreakCalled = true;
break;
}
}
isInComment = true;
outBuffer.append("/*");
i++;
continue;
} else if (!isInQuote && (isInComment || isLineComment) &&
line.regionMatches(false, i, "*/", 0, 2)) {
isInComment = false;
outBuffer.append("*/");
shouldPublish = true;
i++;
continue;
}
if (isInComment || isLineComment) {
outBuffer.append(ch);
if (outBuffer.toString().regionMatches(false, 0, "/*", 0, 2))
outBuffer.insert(0, ' ');
continue;
}
// if we have reached here, then we are NOT in a comment
if (isInHeader) {
isInHeader = false;
currentHeader = (String) openingStack.peek();
} else
currentHeader = null;
foundOrigLineBreak = false;
if (isBreakCalled) {
i--;
break;
}
/**/
if (checkClosingHeader) {
checkClosingHeader = false;
if (bracketBreak)
if (ch != ';') {
i--;
isBreakCalled = true;
break;
} else {
i--;
continue;
}
while (!"{".equals(openingStack.pop()))
;
if (!openingStack.isEmpty()) {
String openingHeader = (String) openingStack.peek();
String closingHeader = (String) closingHeaders.get(openingHeader);
i--;
if (closingHeader == null ||
!line.regionMatches(false, i + 1, closingHeader, 0,
closingHeader.length())) {
if (ch != ';') {
outString = outBuffer.toString();
outBuffer.setLength(0);
break;
} else
i++;
} else {
int lastBufCharPlace = outBuffer.length() - 1;
if ((lastBufCharPlace >= 0) &&
(outBuffer.charAt(lastBufCharPlace) != ' '))
appendSpace(outBuffer);//outBuffer.append(' ');
ch = ' ';
openingStack.pop(); // pop the opening header
continue;
}
}
}
/**/
if (checkIf) {
checkIf = false;
if (line.regionMatches(false, i, "if", 0, 2))
isNewLineNeeded = false;
}
if (!isParenNeeded && checkBlockOpen) {
checkBlockOpen = false;
if (ch == '{' || "static".equals(currentHeader))
isNewLineNeeded = false;
}
if (isNewLineNeeded && !isParenNeeded) {
isNewLineNeeded = false;
//if (!isParenNeeded)
{
i--;
isBreakCalled = true;
continue;
}
}
// handle special characters (i.e. backslash+character such as \n, \t, ...)
if (isSpecialChar) {
outBuffer.append(ch);
isSpecialChar = false;
continue;
}
if (!(isInComment || isLineComment) &&
line.regionMatches(false, i, "\\\\", 0, 2)) {
outBuffer.append("\\\\");
i++;
continue;
}
if (!(isInComment || isLineComment) && ch == '\\') {
isSpecialChar = true;
outBuffer.append(ch);
continue;
}
// handle quotes (such as 'x' and "Hello Dolly")
if (ch == '"' || ch == '\'')
if (!isInQuote) {
quoteChar = ch;
isInQuote = true;
} else if (quoteChar == ch) {
isInQuote = false;
outBuffer.append(ch);
continue;
}
if (isInQuote) {
outBuffer.append(ch);
continue;
}
// handle parenthesies
if (ch == '(' || ch == '[' || ch == ')' || ch == ']') {
if (ch == '(' || ch == '[')
parenDepth++;
else if (ch == ')' || ch == ']')
parenDepth--;
if (parenDepth == 0 && isParenNeeded) {
isParenNeeded = false;
checkBlockOpen = true;
}
//outBuffer.append(ch);
//continue;
}
//don't do special parsing as long as parenthesies are open...
/*
if (parenDepth != 0)
{
outBuffer.append(ch);
continue;
}
*/
/*
if (isNewLineNeeded && !isParenNeeded)
{
isNewLineNeeded = false;
i--;
isBreakCalled = true;
continue;
}
*/
if (prevCh == ' ') {
boolean foundHeader = false;
for (int h = 0; h < headers.length; h++) {
if (line.regionMatches(false, i, headers[h], 0,
headers[h].length())) {
int lineLength = line.length();
int headerEnd = i + headers[h].length();
char endCh = 0;
if (headerEnd < lineLength)
endCh = line.charAt(headerEnd);
if ((headerEnd > lineLength) ||
(endCh >= 'a' && endCh <= 'z') ||
(endCh >= 'A' && endCh <= 'Z') ||
(endCh >= '0' && endCh <= '9'))
break;
foundHeader = true;
outBuffer.append(headers[h]);
i += headers[h].length() - 1;
if ("else".equals(headers[h]))
checkIf = true;
checkBlockOpen = true;
isNewLineNeeded = true;
isBlockNeeded = false;
openingStack.push(headers[h]);
appendSpace(outBuffer);
; //outBuffer.append(' ');
ch = ' ';
int p;
for (p = 0; p < parenHeaders.length; p++)
if (headers[h].equals(parenHeaders[p])) {
isParenNeeded = true;
break;
}
break;
}
}
if (foundHeader) {
isInHeader = true;
continue;
}
}
if (ch == '?')
isInQuestion = true;
if (ch == ':')//isInCase)
{
if (isInQuestion)
isInQuestion = false;
else {
//isInCase = false;
outBuffer.append(ch);
isBreakCalled = true;
continue;
}
}
if (ch == ';' && parenDepth == 0) {
outBuffer.append(ch);
isBreakCalled = true;
continue;
}
if (ch == '{') {
if (!(bracketBreak && isInBracketOpen)) {
boolean isBlockOpener = false;
// first, check if '{' is a block-opener or an static-array opener
isBlockOpener |= (prevNonSpaceCh == '{' &&
((Boolean) bracketBlockStateStack.peek()).
booleanValue());
isBlockOpener |= (prevNonSpaceCh == ')' || prevNonSpaceCh == ';');
isBlockOpener |= isInClassStatement;
isBlockOpener |= (prevNonSpaceCh == ':' && !isInQuestion);
isInClassStatement = false;
if (!isBlockOpener && currentHeader != null) {
for (int n = 0; n < nonParenHeaders.length; n++)
if (currentHeader.equals(nonParenHeaders[n])) {
isBlockOpener = true;
break;
}
}
bracketBlockStateStack.push(new Boolean(isBlockOpener));
if (!isBlockOpener) {
outBuffer.append('{');
continue;
}
}
// if I have reached here, then I am in a block...
if (bracketBreak) {
if (isInBracketOpen) {
isInBracketOpen = false;
} else {
isInBracketOpen = true;
isBreakCalled = true;
i--;
break;
}
}
checkBlockClose = true;
int lastBufCharPlace = outBuffer.length() - 1;
if ((lastBufCharPlace >= 0) &&
(outBuffer.charAt(lastBufCharPlace) != ' '))
appendSpace(outBuffer); //outBuffer.append(' ');
outBuffer.append('{');
openingStack.push("{");
//checkBlockClose = true;
parenDepthsStack.push(new Integer(parenDepth));
parenDepth = 0;
continue;
}
if (ch == '}') {
// first check if this '}' closes a previous block, or a static array...
if (!((Boolean) bracketBlockStateStack.pop()).booleanValue()) {
outBuffer.append(ch);
continue;
}
if (!parenDepthsStack.isEmpty())
parenDepth = ((Integer) parenDepthsStack.pop()).intValue();
outBuffer.append(ch);
checkClosingHeader = true;
continue;
}
if (prevCh == ' ') {
boolean foundHeader = false;
for (int h = 0; h < statementHeaders.length; h++) {
if (line.regionMatches(false, i, statementHeaders[h], 0,
statementHeaders[h].length())) {
int lineLength = line.length();
int headerEnd = i + statementHeaders[h].length();
char endCh = 0;
if (headerEnd < lineLength)
endCh = line.charAt(headerEnd);
if ((headerEnd > lineLength) ||
(endCh >= 'a' && endCh <= 'z') ||
(endCh >= 'A' && endCh <= 'Z') ||
(endCh >= '0' && endCh <= '9'))
break;
isInClassStatement = true;
break;
}
}
}
if (prevCh == ' ' && line.regionMatches(false, i, "return", 0, 6)) {
int lineLength = line.length();
int headerEnd = i + 6;
char endCh = 0;
if (headerEnd < lineLength)
endCh = line.charAt(headerEnd);
if (!((headerEnd > lineLength) || (endCh >= 'a' && endCh <= 'z') ||
(endCh >= 'A' && endCh <= 'Z') ||
(endCh >= '0' && endCh <= '9'))) {
outBuffer.append("return");
i += 5;
currentNonSpaceCh = '-'; // treat 'return' a an operator.
continue;
}
}
// add space when a non-operator follows a closing parenthesis
if ((prevNonSpaceCh == ')' || prevNonSpaceCh == ']') &&
Character.isLetterOrDigit(ch) && ch != '.' &&
ch != '_' && ch != '$' && ch != '(' && ch != '[' &&
ch != ')' && ch != ']')
appendSpace(outBuffer);
if ((!Character.isLetterOrDigit(ch) && ch != '.' && ch != '_' &&
ch != '$' && ch != '(' && ch != '[' && ch != ')' &&
ch != ']') && (Character.isLetterOrDigit(prevNonSpaceCh) ||
prevNonSpaceCh == '.' || prevNonSpaceCh == '_' ||
prevNonSpaceCh == '$' || prevNonSpaceCh == ')' ||
prevNonSpaceCh == ']')) {
boolean isLongOperator = false;
String longOperator = null;
for (int l = 0; l < longOperators.length; l++) {
if (line.regionMatches(false, i, longOperators[l], 0,
longOperators[l].length())) {
isLongOperator = true;
longOperator = longOperators[l];
break;
}
}
if (isLongOperator) {
if (!"--".equals(longOperator) && !"++".equals(longOperator) &&
!".*".equals(longOperator)) {
appendSpace(outBuffer);
outBuffer.append(longOperator);
appendSpace(outBuffer);
ch = ' ';
} else {
outBuffer.append(longOperator);
currentNonSpaceCh = '0'; // hide the operator
}
i += 1; // since all long operators are 2 chars long...
} else if (!(ch == '*' && prevNonSpaceCh == '.'))// not '.*'
{
if (ch != ',' && ch != ';')// && ch != ')' && ch != ']')
appendSpace(outBuffer);
outBuffer.append(ch);
appendSpace(outBuffer);
ch = ' ';
} else
outBuffer.append(ch);
continue;
}
if (ch == ')' || ch == ']')
clearPaddingSpace(outBuffer);
// default
outBuffer.append(ch);
}
try {
tempLine = line.substring(i + (i < line.length() ? 1 : 0));
} catch (Exception e) { /*is this exception really needed??? - check if the above ?: solves the problem...*/
tempLine = "";
}
if (isBreakCalled || isInComment || isLineComment || shouldPublish) {
outString = outBuffer.toString();
outBuffer.setLength(0);
}
if (outString != null && !"".equals(outString))
outString = beautifier.beautify(outString);
else if (ch != '[' && ch != ']' && ch != '(' && ch != ')' &&
ch != '.' && ch != '_' && ch != '$')
appendSpace(outBuffer); //outBuffer.append(" ");
/* if (outString != null && !"".equals(outString)) {
if (isInComment && !isLineComment) {
System.err.println("In Block Comment: " + outString);
StringBuffer s = new StringBuffer(outString);
if ("\t".equals(beautifier.getIndentString())) {
int p = outString.indexOf("\t *");
if (p > -1) {
s.delete(p, p + 4);
s.insert(p, "\t *");
}
}
outString = s.toString();
System.err.println("After replace: " + outString);
}
}*/
return outString;
}
private void appendSpace(StringBuffer buf) {
if (buf.length() == 0 || buf.charAt(buf.length() - 1) != ' ')
buf.append(' ');
}
private void clearPaddingSpace(StringBuffer buf) {
int bufLength = buf.length();
if (bufLength != 0 && buf.charAt(bufLength - 1) == ' ')
buf.setLength(bufLength - 1);
}
}
|
| ... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2024 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.