Findent: indent Fortran sources

Findent: what does it do?

Findent indents Fortran sources. When I was playing at 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 properites 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 complete 'end' statements as 'end subroutine' 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 within 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
#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, except for the option 'convert from free format to fixed format'. 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'

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 job, but lacks a number of the requirements above.