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.

2

6 Answers 6

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Kirill, I copied your sed_script but for some reason I get a command garbled error on line "/^\(if\|else\...". Any idea what might be the reason?
2

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

Comments

1

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...

1 Comment

can you elaborate...i am poor in syntax
1

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.

2 Comments

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 :)
Oh, sorry then :) Maybe you should just start with reading their man pages and + some info on using regular expressions?
0

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

3 Comments

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
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
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.
0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.