README.rst

July 20, 2022 ยท View on GitHub

################################################################################ Roquefort ################################################################################ A tool for R\ efactoring O\ f QUE\ stionable FORT\ ran

Features

Roquefort allows to :

  • Automatically create module to replace existing common blocks <https://github.com/NLESC-JCER/roquefort#remove-common-block>_.
  • Clean unused variable imported from modules <https://github.com/NLESC-JCER/roquefort#clean-unused-imported-variable>_.
  • Automatically transform implicit variable declaration to explicit variable declaration <https://github.com/NLESC-JCER/roquefort/blob/master/README.rst#remove-implicit-variable>_.
  • Move variable to new module <https://github.com/NLESC-JCER/roquefort/blob/master/README.rst#move-variable-in-new-module>_.

Installation

To install roquefort, do:

.. code-block:: console

git clone https://github.com//roquefort.git cd roquefort pip install .

Run tests (including coverage) with:

.. code-block:: console

python setup.py test

Usage

Remove Common block


Common blocks are not unusual to find in Fortran77 code. It recommended to move this common block to modules. The original Fortran code is :

.. code-block:: fortran

subroutine func()

common /mod1/ var1, var2 common /mod2/ var3, var4

implicit real*8(a-h,o-z)

x = var1 y = var2

i = 2

end

To remove common blocks:

.. code-block:: console

python refac_fortran.py --action clean_common -n mod1 -p ./example/

Leads to the code :

.. code-block:: fortran

  subroutine func()


  use mod1, only: var1, var2
  implicit real*8(a-h,o-z)


  common /mod2/ var3, var4


  x = var1
  y = var2

  i = 2

  end

with the additional module file

.. code-block:: fortran

module mod1 !> Arguments: var1, var2 use precision_kinds, only: dp include 'vmc.h'

real(dp) :: var1
real(dp) :: var2
private

public :: var1, var2
save

end module mod1

Clean unused imported variable


Unused varialbe can pollute use statements. For example in the code

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1, var2
  use mod2, only: var3

  implicit none

  integer :: i, j

  i = var1
  j = var3

  end

The variable var2 of mod1 is not used. We can remove that variable with

.. code-block:: console

python refac_fortran.py --action clean_use --filename ../example/test_use.f

Leading to

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1
  use mod2, only: var3

  implicit none

  integer :: i, j

  i = var1
  j = var3

  end

Remove implicit variable


Implicit declaration of variable were common but lead to unclarity in the code. We can remove all implicit declaration and automatically declare variables. For example the code

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1
  use mod2, only: var2

  implicit real*8(a-h,o-z)

  x = var1
  y = var2

  i = 2

  end

implicitly declare variables x, y and i. We can make the declaration implicit with :

.. code-block:: console

python refac_fortran.py --action clean_implicit --filename ../example/test_implicit.f

Leading to :

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1
  use mod2, only: var2

  use precision_kinds, only: dp
  implicit none

  integer :: i
  real(dp) :: x, y

  x = var1
  y = var2

  i = 2

  end

Note that the precision_kinds module needs to be created separately to look like:

.. code-block:: fortran

module precision_kinds implicit none ! named constants for 4, 2, and 1 byte integers: integer, parameter :: & i4b = selected_int_kind(9), & i2b = selected_int_kind(4), & i1b = selected_int_kind(2) ! single, double and quadruple precision reals: integer, parameter :: & sp = kind(1.0), & dp = selected_real_kind(2 * precision(1.0_sp)), & qp = selected_real_kind(2 * precision(1.0_dp)) end module precision_kinds

Move variable in new module


During refactoring of large code base it is sometimes useful to move variable from one module to another. For example in the following code :

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1, var3, var5
  use mod2, only: var2, var7

  implicit real*8(a-h,o-z)

  x = var1
  y = var2

  i = 2

  end

We might wish to move var3 to a new module called modx. This can be done with

.. code-block:: console

python refac_fortran.py --action move_var --var_name var3 --new_module modx --filename ../example/test_move_var.f

Leading to :

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1, var5
  use mod2, only: var2, var7
  use modx, only: var3

  implicit real*8(a-h,o-z)

  x = var1
  y = var2

  i = 2

  end

Note that you need to move the variable from mod1 to modx in the module file separately.

Sort and condense your use statements


During refactoring of large code base it is sometimes useful to reorder the use statements and condense them. For example in the following code :

.. code-block:: fortran

  subroutine func()

  use mod1, only: var1, var3, var5
  use module2, only: var2, var7
  use mod1, only: var1, var3, var5
  use module2, only: var4
  use very_long_module_name, only: longvar1
  use xmod1, only: var8, var9
  use xmod2

  implicit none

  x = var1
  y = var2

  i = 2

  end

We might wish to remove duplicate imports, and condense the existing imports. This can be done with

.. code-block:: console

roquefort condense_use --sort --min_only_offset=20 --max_line_length=72 --overwrite ../example/test_condense_use.f

Leading to :

.. code-block:: fortran

  subroutine func()

  use mod1,    only: var1,var3,var5
  use module2, only: var4,var2,var7
  use very_long_module_name, only: longvar1
  use xmod1,   only: var8,var9
  use xmod2

  implicit none

  x = var1
  y = var2

  i = 2

  end

The min_only_offset argument determines the minimum column where the only statement can start, thus aligning them vertically

Contributing


If you want to contribute to the development of roquefort, have a look at the contribution guidelines <CONTRIBUTING.rst>_.

License


Copyright (c) 2020, Netherlands eScience Center

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Credits


This package was created with Cookiecutter <https://github.com/audreyr/cookiecutter>_ and the NLeSC/python-template <https://github.com/NLeSC/python-template>_.