- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I have some old F77 code (nleq1, horrible-looking but very effective) that I am using in F90 programs. Currently I'm keeping the files separate, with a F90 file that defines a module, and several F77 files (*.f), one of which USEs the module. It's all a bit messy. I'm wondering if there is a way to collect the *.f files together in a module, and/or can a F90 file contain both free-form and fixed-form procedures.
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Well, the simplest way to achieve that is to use the fixed-form altogether and replace the END statement by END SUBROUTINE or END FUNCTION. Then you can join the files into a module:
module my_old_ugly_f77_code contains ... contents of file 1 ... contents of file 2 ... end module
It is possible to format code in such a way that it is acceptable as both fixed-form and free-form, modulo a few nasty aspects of fixed-form (notably the fact that spaces are not really significant - I 20 = 1 is the same as I20 = 1), but why bother? Fixed-form is still acceptable as a way to write Fortran 90 style code. And it makes life quite a bit easier.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Gib, consider whether the FREEFORM and NOFREEFORM compiler directives will help. These directives allow mixing blocks of free form code and blocks of fixed form code in the same source file.
https://software.intel.com/en-us/node/692821#38A9609E-0460-4243-A0F2-C47474F014D4
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks to Arjen and mecej4. I'll need to think about which method makes most sense in this case. It looks as if the compiler directives (which I was unaware of) provide most flexibility.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Using the NOFREEFORM directive I put all the nleq1 files into a module, replacing all the EXTERNAL statements, declaring many undeclared variables, fixing END statements etc. I'm now handling the call-back with procedure(func), another capability that I just learned of. The result is much neater, and I'm very pleased. Thanks.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
One of my students is using gfortran. Unfortunately the !DIR$ directives do not appear to be supported by gfortran :(
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Yes, that is a risk with any non-standard features. I do not know if gfortran has an equivalent feature, but it may be worth trying to find out. The alternative is to separate the fixed-form and free-form parts into separate files. Fixed-form still allows all the benefits of modern Fortran. the only thing you cannot do is make a single module, although you can combine modules into a single one (joining the interfaces, not the modules as such)
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
You may try the Silverfrost FTN95 compiler's /CONVERT option and do a one-time conversion from fixed source form to free form, see http://www.silverfrost.com/ftn95-help/options/quick_reference.aspx . There are tools such as SPAG that also do code conversions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
gib wrote:
One of my students is using gfortran. Unfortunately the !DIR$ directives do not appear to be supported by gfortran :(
@gib,
Students should all be trained to use SUBMODULEs, PRONTO! And to use standard language features as much as possible and consider minimal use of compiler directives and options.
See if the fixed-form code can be wrapped in SUBMODULEs and be provided with the MODULE prefix, as follows:
module collect_m interface module subroutine fugly1( a1, a2, ..) ! Interface to fixed-form procedure fugly1 <type> a1 <type> a2 end subroutine fugly1 module function fugly2( b1, b2, ..) ! Interface to fixed-form procedure fugly2 <type> b1 <type> a2 end function fugly2 end interface contains subroutine sub1( .. ) .. end subroutine function f1( .. ) .. end function f1 end module
SUBMODULE(COLLECT_M) FUGLY1_SM IMPLICIT NONE CONTAINS MODULE SUBROUTINE FUGLY1(A1, A2, ..) <TYPE> A1 <TYPE> A2 .. RETURN END SUBROUTINE FUGLY1 END SUBMODULE FUGLY1_SM
SUBMODULE(COLLECT_M) FUGLY2_SM IMPLICIT NONE CONTAINS MODULE FUNCTION FUGLY2(B1, B2, ..) <TYPE> B1 <TYPE> B2 .. RETURN END SUBROUTINE FUGLY2 END SUBMODULE FUGLY2_SM
So note the fixed-form code represented by FUGLY1 and FUGLY2 above are pretty retained as-is, all that is done is standard attributes to wrap such code.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's not a very appealing solution, FortranFan, because there are so many subroutines and functions.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks mecej4, the Silverfrost FTN95 compiler with the /CONVERT option looks interesting - free for personal use. I might give it a try.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
On Silverfrost /CONVERT - I installed it and ran the conversion on a fixed-form .f file. The result is if anything even uglier than the original. Interestingly, the .f file has this line
PARAMETER (ZERO = 0.0 D0)
which is accepted by ifort. The same line appears in the converted free-form .f90 file, but now in ifort the space creates an error. When the space is removed the file compiles, so that's success. Obviously a change between f77 and f90. It still needs some attention before being packaged in a module (END statements need to be completed), but that is relatively minor. It also strips out all the comments, which is not very friendly.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Note there are other such programs available (Alan Miller and Michael Metcalfe have written and published such programs for instance). Whether they produce something in the style you want will depend.
As for PARAMETER (ZERO = 0.0 D0) not being accepted in free-form: that is one of the few incompatibilities between the two source forms. In fixed form spaces essentially have no particular meaning, in free form they do.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
gib wrote:
That's not a very appealing solution, FortranFan, because there are so many subroutines and functions.
Suit yourself, but anyone else interested in refactoring their code will note:
- the compiler option /gen-interfaces (https://software.intel.com/en-us/fortran-compiler-18.0-developer-guide-and-reference-gen-interfaces) can be used to achieve a decent initial state of interfaces of all the existing legacy code that is usually in fixed-form source format and without explicit interfaces.
- Then one can use any of the scripting options (e.g., Perl) to quickly absorb the interfaces into a module and to wrap the legacy code in SUBMODULEs. Note with SUBMODULEs one does not materially need to change the legacy code in any way; it can even remain in fixed-format source form which is also supported by the current Fortran standard. One only prepends and appends 'stuff' to the source.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page