From 2a96ef59405690bf5eeb95e9dd1ed1a45d32b472 Mon Sep 17 00:00:00 2001 From: benfry Date: Sat, 7 May 2005 04:21:57 +0000 Subject: [PATCH] incorporate martin's auto format code --- processing/app/Editor.java | 2 +- processing/app/tools/AutoFormat.java | 905 ++++++++++++++++++++++++++- 2 files changed, 880 insertions(+), 27 deletions(-) diff --git a/processing/app/Editor.java b/processing/app/Editor.java index 51e0b5b80..e6f6ae11d 100644 --- a/processing/app/Editor.java +++ b/processing/app/Editor.java @@ -581,7 +581,7 @@ public class Editor extends JFrame JMenuItem item; JMenu menu = new JMenu("Tools"); - item = new JMenuItem("Auto Format"); + item = newJMenuItem("Auto Format", 'F', true); item.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new AutoFormat(Editor.this).show(); diff --git a/processing/app/tools/AutoFormat.java b/processing/app/tools/AutoFormat.java index 59579f305..3e1a2f8da 100644 --- a/processing/app/tools/AutoFormat.java +++ b/processing/app/tools/AutoFormat.java @@ -3,8 +3,8 @@ /* Part of the Processing project - http://processing.org - Copyright (c) 2004-05 Ben Fry and Casey Reas - Copyright (c) 2001-04 Massachusetts Institute of Technology + Copyright (c) 2005 Ben Fry and Casey Reas + Copyright (c) 2003 Martin Gomez, Ateneo de Manila University This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -26,33 +26,13 @@ package processing.app.tools; import processing.app.*; import processing.core.*; -import java.awt.*; -import java.awt.event.*; import java.io.*; -import java.util.*; - -import javax.swing.*; -import javax.swing.border.*; -import javax.swing.event.*; +import java.util.StringTokenizer; /** - * Basic but buggy handler for cleaning up code. - *
- * an improved algorithm that would still avoid a full state machine
- * 1. build an array of strings for the lines
- * 2. first remove everything between / * and * / (relentless)
- * 3. next remove anything inside two sets of " "
- *    but not if escaped with a \
- *    these can't extend beyond a line, so that works well
- *    (this will save from "http://blahblah" showing up as a comment)
- * 4. remove from* to the end of a line everywhere
- * 5. run through remaining text to do indents
- *    using hokey brace-counting algorithm
- * 6. also add indents for switch statements
- *    case blah: { }  (colons at end of line isn't a good way)
- *    maybe /case \w+\:/
- * 
+ * Alternate handler for dealing with auto format, + * contributed by Martin Gomez. */ public class AutoFormat { Editor editor; @@ -63,13 +43,14 @@ public class AutoFormat { } + /* public void show() { String prog = editor.textarea.getText(); // TODO re-enable history //history.record(prog, SketchHistory.BEAUTIFY); - int tabSize = Preferences.getInteger("editor.tabs.size"); + //int tabSize = Preferences.getInteger("editor.tabs.size"); char program[] = prog.toCharArray(); StringBuffer buffer = new StringBuffer(); @@ -157,4 +138,876 @@ public class AutoFormat { editor.sketch.setModified(); //buttons.clear(); } + */ + + + StringBuffer strOut; + String formattedText; + int indentValue; + String indentChar; + String uhOh = null; + String theStuff; + int EOF; + BufferedInputStream bin = null; + int nBytesRead, indexBlock, lineLength, lineNumber; + byte bArray[]; + String strBlock; + int s_level[]; + int c_level; + int sp_flg[][]; + int s_ind[][]; + int s_if_lev[]; + int s_if_flg[]; + int if_lev, if_flg, level; + int ind[]; + int e_flg, paren; + static int p_flg[]; + char l_char, p_char; + int a_flg, q_flg, ct; + int s_tabs[][]; + String w_if_, w_else, w_for, w_ds, w_case, w_cpp_comment, w_jdoc; + int jdoc, j; + int BLOCK_MAXLEN; + char string[]; + byte bstring[]; + byte bblank; + char cc; + int s_flg, b_flg; + int peek; + char peekc; + int tabs; + char next_char, last_char; + char lastc0, lastc1; + char c, c0; + char w_kptr; + + String line_feed; + + static int outfil; // temporary + + + public void comment() { + int save_s_flg; + save_s_flg = s_flg; + + int done = 0; + c = string[j++] = getchr(); // extra char + while (done == 0) { + c = string[j++] = getchr(); + while(c != '/') { + if(c == '\n' || c == '\r') { + lineNumber++; + putcoms(); + s_flg = 1; + } + c = string[j++] = getchr(); + } + String tmpstr = new String(string); + if (j>1 && string[j-2] == '*') { + done = 1; + jdoc = 0; + } + } + + putcoms(); + s_flg = save_s_flg; + jdoc = 0; + return; + } + + + public char get_string() { + char ch; + ch = '*'; + while (true) { + switch (ch) { + default: + ch = string[j++] = getchr(); + if (ch == '\\') { + string[j++] = getchr(); + break; + } + if (ch == '\'' || ch == '"') { + cc = string[j++] = getchr(); + while (cc != ch) { + if (cc == '\\') string[j++] = getchr(); + cc = string[j++] = getchr(); + } + break; + } + if (ch == '\n' || ch == '\r') { + indent_puts(); + a_flg = 1; + break; + } else { + return(ch); + } + } + } + } + + + public void indent_puts() { + string[j] = '\0'; + if (j > 0) { + if (s_flg != 0) { + if((tabs > 0) && (string[0] != '{') && (a_flg == 1)) { + tabs++; + } + p_tabs(); + s_flg = 0; + if ((tabs > 0) && (string[0] != '{') && (a_flg == 1)) { + tabs--; + } + a_flg = 0; + } + String j_string = new String(string); + strOut.append(j_string.substring(0,j)); + for (int i=0; i 0)string[j++] = c; + indent_puts(); + s_flg = 0; + break; + } + if(s_flg == 0 || j > 0)string[j++] = c; + break; + case '\r': /* for MS Windows 95 */ + case '\n': + lineNumber++; + if (EOF==1) + { + break; + } + String j_string = new String(string); + + e_flg = lookup(w_else); + if(e_flg == 1) gotelse(); + if (lookup_com(w_cpp_comment) == 1) + { + if (string[j] == '\n') + { + string[j] = '\0'; + j--; + } + } + + indent_puts(); + fprintf(outfil, line_feed); + s_flg = 1; + if(e_flg == 1) + { + p_flg[level]++; + tabs++; + } + else + if(p_char == l_char) + { + a_flg = 1; + } + break; + case '{': + if(lookup(w_else) == 1)gotelse(); + s_if_lev[c_level] = if_lev; + s_if_flg[c_level] = if_flg; + if_lev = if_flg = 0; + c_level++; + if(s_flg == 1 && p_flg[level] != 0) + { + p_flg[level]--; + tabs--; + } + string[j++] = c; + indent_puts(); + getnl() ; + indent_puts(); + fprintf(outfil,"\n"); + tabs++; + s_flg = 1; + if(p_flg[level] > 0) + { + ind[level] = 1; + level++; + s_level[level] = c_level; + } + break; + case '}': + c_level--; + if (c_level < 0) + { + EOF = 1; + string[j++] = c; + indent_puts(); + break; + } + if((if_lev = s_if_lev[c_level]-1) < 0)if_lev = 0; + if_flg = s_if_flg[c_level]; + indent_puts(); + tabs--; + p_tabs(); + peekc = getchr(); + if( peekc == ';') + { + onechar = new StringBuffer(); + onechar.append(c); /* } */ + onechar.append(';'); + fprintf(outfil, onechar.toString()); + peek = -1; + peekc = '`'; + } + else + { + onechar = new StringBuffer(); + onechar.append(c); + fprintf(outfil, onechar.toString()); + peek = 1; + } + getnl(); + indent_puts(); + fprintf(outfil,"\n"); + s_flg = 1; + if(c_level < s_level[level]) + if(level > 0) level--; + if(ind[level] != 0) + { + tabs -= p_flg[level]; + p_flg[level] = 0; + ind[level] = 0; + } + break; + case '"': + case '\'': + string[j++] = c; + cc = getchr(); + while(cc != c) + { + // max. length of line should be 256 + string[j++] = cc; + + if(cc == '\\') + { + cc = string[j++] = getchr(); + } + if(cc == '\n') + { + lineNumber++; + indent_puts(); + s_flg = 1; + } + cc = getchr(); + + } + string[j++] = cc; + if(getnl() == 1) + { + l_char = cc; + peek = 1; + peekc = '\n'; + } + break; + case ';': + string[j++] = c; + indent_puts(); + if(p_flg[level] > 0 && ind[level] == 0) + { + tabs -= p_flg[level]; + p_flg[level] = 0; + } + getnl(); + indent_puts(); + fprintf(outfil,"\n"); + s_flg = 1; + if(if_lev > 0) + if(if_flg == 1) + { + if_lev--; + if_flg = 0; + } + else if_lev = 0; + break; + case '\\': + string[j++] = c; + string[j++] = getchr(); + break; + case '?': + q_flg = 1; + string[j++] = c; + break; + case ':': + string[j++] = c; + peekc = getchr(); + if(peekc == ':') + { + indent_puts(); + fprintf (outfil,":"); + peek = -1; + peekc = '`'; + break; + } + else + { + int double_colon = 0; + peek = 1; + } + + if(q_flg == 1) + { + q_flg = 0; + break; + } + if(lookup(w_ds) == 0 && lookup(w_case) == 0) + { + s_flg = 0; + indent_puts(); + } + else + { + tabs--; + indent_puts(); + tabs++; + } + peekc = getchr(); + if(peekc == ';') + { + fprintf(outfil,";"); + peek = -1; + peekc = '`'; + } + else + { + peek = 1; + } + getnl(); + indent_puts(); + fprintf(outfil,"\n"); + s_flg = 1; + break; + + case '/': + c0 = string[j]; + string[j++] = c; + peekc = getchr(); + + if(peekc == '/') + { + string[j++] = peekc; + peekc = '`'; + peek = -1; + cpp_comment(); + fprintf(outfil,"\n"); + break; + } + else + { + peek = 1; + } + + if(peekc != '*') { + break; + } + else + { + if (j > 0) string[j--] = '\0'; + if (j > 0) indent_puts(); + string[j++] = '/'; + string[j++] = '*'; + peek = -1; + peekc = '`'; + comment(); + break; + } + case '#': + string[j++] = c; + cc = getchr(); + while(cc != '\n') + { + string[j++] = cc; + cc = getchr(); + } + string[j++] = cc; + s_flg = 0; + indent_puts(); + s_flg = 1; + break; + case ')': + paren--; + if (paren < 0) + { + EOF = 1; + } + string[j++] = c; + indent_puts(); + if(getnl() == 1) + { + peekc = '\n'; + peek = 1; + if(paren != 0) + { + a_flg = 1; + } + else if(tabs > 0) + { + p_flg[level]++; + tabs++; + ind[level] = 0; + } + } + break; + case '(': + string[j++] = c; + paren++; + if ((lookup(w_for) == 1)) + { + c = get_string(); + while(c != ';') c = get_string(); + ct=0; + int for_done = 0; + while (for_done==0) + { + c = get_string(); + while(c != ')') + { + if(c == '(') ct++; + c = get_string(); + } + if(ct != 0) + { + ct--; + } + else for_done = 1; + } /* endwhile for_done */ + paren--; + if (paren < 0) + { + EOF = 1; + } + indent_puts(); + if(getnl() == 1) + { + peekc = '\n'; + peek = 1; + p_flg[level]++; + tabs++; + ind[level] = 0; + } + break; + } + + if(lookup(w_if_) == 1) + { + indent_puts(); + s_tabs[c_level][if_lev] = tabs; + sp_flg[c_level][if_lev] = p_flg[level]; + s_ind[c_level][if_lev] = ind[level]; + if_lev++; + if_flg = 1; + } + } /* end switch */ + + String j_string = new String(string); + + } // end while not EOF + + //formattedText = strOut.toString(); + + // save current (rough) selection point + int selectionEnd = editor.textarea.getSelectionEnd(); + + // replace with new bootiful text + editor.setText(strOut.toString(), false); + + // make sure the caret would be past the end of the text + if (strOut.length() < selectionEnd - 1) { + selectionEnd = strOut.length() - 1; + } + + // at least in the neighborhood + editor.textarea.select(selectionEnd, selectionEnd); + + editor.sketch.setModified(); + + bin.close(); // close buff + + } catch (IOException ioe) { + editor.error(ioe); + //ioe.printStackTrace(); + } + + + // () {} check + + String ck_paren = new String("left"); + if (paren < 0) ck_paren = "right"; + + if (paren != 0) { + setUhOh("Uh oh... too many " + ck_paren + " parentheses."); + + } else { // check braces only if parens are ok + ck_paren = "left"; + if (c_level < 0) { + ck_paren = "right"; + } else if (c_level != 0) { + setUhOh("Uh oh... too many " + ck_paren + " curled braces."); + } + } + } + + + /* throw back the stuff to the editor */ + public String getFormattedText() + { + return formattedText; + } + + + /* special edition of put string for comment processing */ + public void putcoms() + { + int i = 0; + int sav_s_flg = s_flg; + if(j > 0) + { + if(s_flg != 0) + { + p_tabs(); + s_flg = 0; + } + string[j] = '\0'; + i = 0; + while (string[i] == ' ') i++; + if (lookup_com(w_jdoc) == 1) jdoc = 1; + String strBuffer = new String(string,0,j); + if (string[i] == '/' && string[i+1]=='*') + { + if ((last_char != ';') && (sav_s_flg==1) ) + { + fprintf(outfil, strBuffer.substring(i,j)); + } + else + { + fprintf(outfil, strBuffer); + } + } + else + { + if (string[i]=='*' || jdoc == 0) + fprintf (outfil, " "+strBuffer.substring(i,j)); + else + fprintf (outfil, " * "+strBuffer.substring(i,j)); + } + j = 0; + string[0] = '\0'; + } + } + + public void cpp_comment() + { + c = getchr(); + while(c != '\n' && c != '\r' && j<133) + { + string[j++] = c; + c = getchr(); + } + lineNumber++; + indent_puts(); + s_flg = 1; + } + + + /* expand indentValue into tabs and spaces */ + public void p_tabs() + { + int i,k; + + if (tabs<0) tabs = 0; + if (tabs==0) return; + i = tabs * indentValue; // calc number of spaces + //j = i/8; /* calc number of tab chars */ + + for (k=0; k < i; k++) { + strOut.append(indentChar); + } + } + + + public char getchr() + { + if((peek < 0) && (last_char != ' ') && (last_char != '\t')) + { + if((last_char != '\n') && (last_char != '\r')) + p_char = last_char; + } + if(peek > 0) /* char was read previously */ + { + last_char = peekc; + peek = -1; + } + else /* read next char in string */ + { + indexBlock++; + if (indexBlock >= lineLength) + { + for (int ib=0; ib 0) + { + nBytesRead = bin.read(bArray); + lineLength = nBytesRead; + strBlock = new String(bArray); + indexBlock = 0; + last_char = strBlock.charAt(indexBlock); + peek = -1; + peekc = '`'; + } + else + { + EOF = 1; + peekc = '\0'; + } + } + catch(IOException ioe) + { + System.out.println(ioe.toString()); + } + } + else + { + last_char = strBlock.charAt(indexBlock); + } + } + peek = -1; + if (last_char == '\r') + { + last_char = getchr(); + } + + return last_char; + } + + /* else processing */ + public void gotelse() + { + tabs = s_tabs[c_level][if_lev]; + p_flg[level] = sp_flg[c_level][if_lev]; + ind[level] = s_ind[c_level][if_lev]; + if_flg = 1; + } + + /* read to new_line */ + public int getnl() + { + int save_s_flg; + save_s_flg = tabs; + peekc = getchr(); + while(peekc == '\t' || peekc == ' ') + { + string[j++] = peekc; + peek = -1; + peekc = '`'; + peekc = getchr(); + peek = 1; + } + peek = 1; + + if (peekc == '/') + { + peek = -1; + peekc = '`'; + peekc = getchr(); + if (peekc == '*') + { + string[j++] = '/'; + string[j++] = '*'; + peek = -1; + peekc = '`'; + comment(); + } + else if (peekc == '/') + { + string[j++] = '/'; + string[j++] = '/'; + peek = -1; + peekc = '`'; + cpp_comment(); + return (1); + } + else + { + string[j++] = '/'; + peek = 1; + } + } + peekc = getchr(); + if(peekc == '\n') + { + lineNumber++; + peek = -1; + peekc = '`'; + tabs = save_s_flg; + return(1); + } + else + { + peek = 1; + } + return 0; + } + + public int lookup (String keyword) + { + char r; + int l,kk,k,i; + String j_string = new String(string); + + if (j<1) return (0); + kk=0; + while(string[kk] == ' ')kk++; + l=0; + l = j_string.indexOf(keyword); + if (l<0 || l!=kk) + { + return 0; + } + r = string[kk+keyword.length()]; + if(r >= 'a' && r <= 'z') return(0); + if(r >= 'A' && r <= 'Z') return(0); + if(r >= '0' && r <= '9') return(0); + if(r == '_' || r == '&') return(0); + return (1); + } + + public int lookup_com (String keyword) + { + char r; + int l,kk,k,i; + String j_string = new String(string); + + if (j<1) return (0); + kk=0; + while(string[kk] == ' ')kk++; + l=0; + l = j_string.indexOf(keyword); + if (l<0 || l!=kk) + { + return 0; + } + return (1); + } } \ No newline at end of file