views:

353

answers:

6

I know this is silly but I can't overcome my curiosity. Is it possible to write a shell script to format a piece of java code?

For example, if a user writes in a code:

    public class Super{
    public static void main(String[] args){
    System.out.println("Hello world");
    int a=0;
    if(a==100)
    {
    System.out.println("Hello world");
    }
    else
    {
    System.out.println("Hello world with else");
    }
    }
}

I would like to write a shell script which would make the code like this.

 public class Super
 {
  public static void main(String[] args)
  {
   System.out.println("Hello world");
   int a=0;
   if(a==100){
    System.out.println("Hello world");
   }
   else{
    System.out.println("Hello world with else");
   }
}

To be precise, we should change the formatting of flower brackets. If it is try/catch or control structures we should change it to same line and if it is function/method/class it should come in next line.I have little knowledge about sed and awk which can do this task so easily. Also I know this can be done using eclipse.

A: 

Have a look at the CLI for Jalopy. Jalopy is a pretty powerful source formatter.

Rich Seller
I just want to know is it possible to do through shell script.There are umpteen softwares to format the code but I am asking is it possible with awk or sed
Harish
Fair enough. Though I'd make it clear near the top of your question that you are doing this as a learning exercise for sed/awk, or you'll get a host of answers like mine
Rich Seller
Agreed. Shell scripts execute programs. If there is a limited number of programs, you should mention that in the question. I imagined the question was because one wanted to reformat a huge number of files, or wanted to reformat on commit to a source repository. I would suggest the script invokes vim, which as pretty flexible reformatting capabilities.
brianegge
+1  A: 

It is definitely possible... I just don't understand why you would want to spend your time doing it? :] There are enough tools to do that and any decent IDE provides a way to re-format the source code (including Eclipse).

For example, to format in Eclipse 3.4 (should be similar in other versions) just right click on your project or a file and select "Source > Format" from the menu.

And if you need to change the way it formats the code, just go to the "Preferences > Java > Code Style > Formatter" and change the template. As far as I know, it is very similar in JDeveloper and NetBeans.

Slink84
Yes mate.Just want to learn more about sed and awk more.I thought some of the experts would give some idea about it.Even I had mentioned that its silly :)
Harish
Oh, sorry then :) Maybe you should just start with reading their man pages and + some info on using regular expressions?
Slink84
+1  A: 

I think this could be done through a simple 'sed' script. Use 1 variable (bCount) that stores the amount of '{' (opening brackets) - (minus) the amount of '}' (closing brackets) Then I would go through the file and insert 'tabs' according to the actual count of bracets that are used. So

public class Super{ //bCount=0
public static void main(String[] args){ //bCount=1
System.out.println("Hello world"); //bCount=2
int a=0; //bCount=2
....and so on

so instert 0 tabs on line 0

1 tab on line 1

2 tabs on line 3 and 4 and so on...

cb0
can you elaborate...i am poor in syntax
Harish
+2  A: 

A quick, flawed attempt, but one that works on your sample input:

BEGIN {depth = 0;}
/{$/  {depth = depth + 1}
/^}/  {depth = depth - 1}
      {prefix = ""; for (i = 0; i < depth; i++) { prefix = prefix "  "} print prefix $0 ; }

This is an awk script: place it in a file and do

awk -f awk_script_file source_file

Obvious flaws with this include:

  • It doesn't catch braceless places where you'd like indentation like

    if (foo)
      bar();
    
  • It will modify the indent depth based on braces in comments and string literals

  • It won't detect { braces followed by comments
Sbodd
brilliant work mate.Appreciate your time mate
Harish
+2  A: 

Well, I've had some free time on my hands, so I decided to relive my good old linux days :]

After reading a bit about awk and sed, I've decided that it might be better to use both, as it is easier to add indentation in awk and parse strings in sed.

Here is the ~/sed_script that formats the source file:

    # delete indentation
    s/^ \+//g

    # format lines with class
    s/^\(.\+class.\+\) *\({.*\)$/\1\n\2/g

    # format lines with methods
    s/^\(public\|private\)\( \+static\)\?\( \+void\)\? \+\(.\+(.*)\) *\({.*\)$/\1\2\3 \4\n\5/g

    # format lines with other structures
    /^\(if\|else\|for\|while\|case\|do\|try\)\([^{]*\)$/,+1 {   # get lines not containing '{'
                                                            # along with the next line
      /.*{.*/ d             # delete the next line with '{'
      s/\([^{]*\)/\1 {/g    # and add '{' to the first line
    }

And here is the ~/awk_script that adds indentation:

    BEGIN { depth = 0 }
    /}/   { depth = depth - 1 }
          {
              getPrefix(depth)
              print prefix $0
          }
    /{/   { depth = depth + 1 }

          function getPrefix(depth) {
              prefix = ""
              for (i = 0; i < depth; i++) { prefix = prefix "    "}
              return prefix
          }

And you use them like that:

    > sed -f ~/sed_script ~/file_to_format > ~/.tmp_sed
    > awk -f ~/awk_script ~/.tmp_sed

It is far from proper formatting tool, but I hope it will do OK as a sample script for reference :] Good luck with your learning.

Slink84
Amazing....You rock dude...
Harish
Sick. Fascinating… but, surely a sign of a twisted mind ;-)
Paul Wagland
A: 

Consider using Jindent, which is a "a simple Java Indent Tool using Emacs". It's a free shell script which is a part of the Ptolemy project at Berkeley.

Adam Matan