Findent: indent Fortran sources

Breaking news: findent now supports coco preprocessor statements AND can convert from free to fixed format.

Findent: what does it do?

Findent indents Fortran sources. When I was playing at https://www.surfsara.nl, I parallelized a number of Fortran programs. The first things I used to do were:

  • convert to Fortran90, using modules, to enable the compiler to detect silly mistakes
  • indent the sources

For indenting I used gvim, which does a reasonable job, but far from perfect. Understandable: parsing Fortran with vimscript is not easy, especially if it has to be fast.

Desirable properties of a Fortran indenter

I think a Fortran indenter should have the following properties:

  • indents correctly old fashioned and modern Fortran
  • indents fixed and free format, the amount of indent decided by the user
  • indenting is increased at 'subroutine', 'module', 'function', 'select case', 'do', and so on, and decreased as appropriate
  • is capable to convert from fixed format to free format, and the other way around
  • is capable to convert 'end' statements to 'end subroutine', 'end program' or 'end module' statements to facilitate the conversion from Fortran-77 to Fortran-90
  • does not 'beautify' the source: if I put 3 spaces somewhere in the middle of a line, they should be preserved
  • does not break long lines: every decent compiler can handle long lines
  • is capable to process 'tabbed input' (i.e. a tab is used in the first 6 characters of a fixed-format Fortran line)
  • indents correctly from Fortran-4 to Fortran-2008 or later
  • it works on a line-per-line basis, so that the indenting can start anywhere

The indenter does not have to parse a Fortran statement completely, but it should not be easily fooled by constructs like:

      do 10 i=1.10 ! this is not a do statement, but an assignment to the variable 'do10i'
      done = 20 ! this is an assignment to the variable 'done'
      subroutine(x) = 20 ! not a subroutine statement
      realfunctioncalc(x) ! must be recognized as a function statement
      do 10 i=1,n
        do 10 j=1,m
           ...
 10   continue ! this must be recognized as ending two loops

#ifdef one 
!      the indenter should be capable to see that this is only one do statement, 
!      and not indent twice
     do i =1,1
#else
    do i=1,n
#endif

And it would be nice if the program runs in Linux, Windows and OS X.

Creating findent

I decided to try to write a Fortran indenter, using the requirements above. It took me more time than I thought, but in the end I am very happy with the result, especially because the easy interoperability with gvim. I did my best to fulfil all requirements above. The program is developed using Linux (Ubuntu), g++, flex and bison.

As a bonus, I wrote a graphical front end, written in Java, and baptised 'jfindent' . (It appears that practically nobody is interested in jfindent).

Using findent in vim, gedit and emacs

Findent optionally outputs configuration files for usage with vim or gedit and emacs, see findent --help.

Using findent in eclipse

I was not able to find out how to incorporate findent in eclipse and would really appreciate it if somebody could help me out.

Other Fortran indenters

Good free Fortran indenters are 'not easy to find'. Searching the Internet, I was not able to find good working free available Fortran indenters, with the exception of f90ppr. F90ppr is written in Fortran and does a nice and quick job, but lacks a number of the requirements above.

A more recent development is fprettify, written in Python. IMHO the software is not mature enough for use in serious projects.