There is a large legacy code written in F77 that I’m trying to bring back to life. I will manually reorganize routines into modules that make sense for the problem in question, and similar. But the most painstaking part is de-spaghetization of the old go-to dominated code. I remember using some free automatic translator for a similar problem 10+ years ago, but cannot trace it now. Can anyone recommend me some (preferably free) tool for this task? Many thanks!!
There is the late Alan Miller’s to_f90.f90
! Takes Fortran 77 code in standard format and makes some changes to produce
! free-format Fortran 90 code.
! N.B. It expects STANDARD F77 code. Non-standard extensions such as
! DO … END DO (i.e. no label) or in-line comments may cause havoc!
! Changes included are:
! C or c in column 1 replaced with !
! Continuation denoted by a character in column 6 replaced with & at the
! end of the previous line.
! Indenting of code for DO-loops and IF blocks.
! END of program unit replaced by END SUBROUTINE (/PROGRAM/FUNCTION) name
! Fortran `keywords’ are in upper case, all other words other than those
! in character strings are converted to lower case.
! .LT., .EQ., etc. replaced with <, ==, etc.
! Labels removed from DO loops; all of which will end with END DO.
! If labels are not referenced, they are removed.
! Short continued lines are adjoined to the previous line.
! ENDIF, ELSEIF & GOTO split into separate words.
! 3-way arithmetic IF constructs are converted to IF … ELSE IF form.
! Embedded blanks are removed from numbers in DATA statements.
! INTENT declarations are added for dummy arguments.
! Some GO TOs are converted to CYCLE or EXIT.
! Converts CHARACTER * to CHARACTER (LEN=xx) ::.
! Converts computed GO TOs to SELECT CASE.
There’s Mike Metcalf’s convert.f90 program. I don’t remember if or how it deals with
goto spaghetti code.
I seem to recall a recent effort on a Fortran code modernizer from NCAR. You might include NCAR in a Google search.
I am always skeptical of conversions - the hard part is making sure that the converted program behaves correctly. I was once approached by a company who wanted to convert their application from an unusual vendor variant of F77 to something more modern. My first question was “what sort of test system do you have to ensure that the results are correct?” Answer: “We don’t”. I turned down the job.
I am doubtful that any sort of automatic translator will 100% convert the program’s logic into anything you can use.
See this very nice blog site by Jacob Williams and the summary on converter tools there.
Re: f2f, a Perl script converter by Colby Lemon, unfortunately the original link is broken but someone has been kind enough to make it available at GitHub: f2f_online link.
My own earnest personal advice: “just do it”! As goes the now clichéd expression, the only thing you would have to fear is fear itself!
You can follow the usual code refactoring and modernization steps:
- Employ a suitable source code control system and create a project repository in it for this legacy code and check all the current code in it,
- Create as comprehensive a regression test suite for current legacy code and don’t be surprised if the current code fails most of them!
- Create a branch of the project in your source code control system for a modern incarnation,
- Use one or more converter tools from the link above to create free-form source version of the code in this branch,
- “Modularize” the converted code and organize them in Fortran MODULEs (and SUBMODULEs),
- Refactor the converted code and employ constructs toward structured programming as much as possible e.g., SELECT CASE, named DO LOOPs with EXIT instead of GO TOs, BLOCK constructs with EXIT in situations where IF THEN ELSE blocks appear too deeply nested and/or convoluted, and so forth,
- Make sure to check in the refactored code in your source code control system at some regular frequency (daily?),
- Document your observations and also code details heavily as you refactor,
- Continue until you sense you have reached the point of diminishing returns for your effort,
- Then rectify the code until you have a working program.
- Debug and bug-fix the new code until all the tests in the regression suite pass.
- Once you succeed, you can make your branch in the source code control system the “production” one and mark the original repository as legacy.
Thank you all for great answers! I’ll give it a try with small bits of code to figure our which one does the best job.
You are totally right. And even if the tests exist, they usually cover only a small subset of the possible runs. So I see this task more as rewriting and reviving the old code, than as a simple conversion. In the end, one of the most important thing is to reorganize it into modules that are semantically related and there is no code for that. Still, some subroutines are rather straight forward and it would be great to save some time on these ones, at least on the tasks like reformatting.
Great! f2f was the routine I used long time ago and it was doing a pretty neat job.
Your strategy makes a lot of sense! I would probably intuitively take a similar route, but it’s nice to have it spelled out like this! It is an especially good advice to use version control from the very beginning. Many thanks!!