|
|
You have half a million lines of VMS
Fortran which has to go to Linux, Unix or Windows. A trial compilation
on the new host was disastrous.
What are the problems, and how can you deal with them?
|
|
Here is a script which converts Fortran code from VMS to Unix, Linux or
Windows. The idea is to convert the code in a single automated pass,
so you never have intermediate files in a state which won't run on either
the original or the target host. WinFPT or FPT will typically convert a quarter of
a million lines in 2 or 3 minutes.
The % character introduces a command to WinFPT or FPT and ! delimits a comment.
! vms_to_unix.fsp
! ===============
! File name handling
! ==================
! Input files
! -----------
% primary input file name extension: ".for"
% include input file name extension: ".inc"
% edit input file names : lower case
% define "AERO:" "/home/simulator/aero"
! Output files
! ------------
% lower case file names
% primary output file name extension: '.f'
% include output file name extension: '.i'
% maximum base file name length: 128
! Structural Changes
! ==================
% change isam file accesses to sub-program calls
% correct inconsistent arguments
% correct missing arguments
! Local changes
! =============
% no tab
% change hex numebers to Fortran 90 format
% change octal numbers to fortran 90 format
% change parameter statements to standard form
% change call function to function invocation
% change dictionary to include
% correct use of integer for logical
% change .eq. to .eqv. for logicals
% remove %descr
% evaluate intrinsics in parameter statements
% replace embedded expressions in formats
% insert subroutine to translate file names
! End of vms_to_unix.fsp
|
|
The commands deal with the situation where the include statements use
logical names, where the file names are written in random case, and where
they are written with and without extensions. You might see the same file
referenced by:
INCLUDE 'AERO:DRAG_COMMON.INC'
INCLUDE 'DUA1:[david.simulator.aero]drag_common'
INCLUDE 'drag_common.inc'
The FPT commands convert all of these on-the-fly. This is not a major issue -
you can do it with global edits, but then the files won't compile on the
VAX. Also, the only way to set it up by hand is with repeated trial
and error passes with the compiler, which can be time consuming.
The include statements in the output files are in the format for the
new host. For example:
INCLUDE 'drag_common.i'
|
|
WinFPT or FPT will change ISAM files accesses to subroutine calls.
For example, starting with:
OPEN (UNIT=INDXUFLUN,ACCESS='SEQUENTIAL'
1 ,FILE='INDXUF.DAT',RECL=10,STATUS='NEW'
1 ,ORGANIZATION='INDEXED'
1 ,KEY=(1:4:INTEGER,5:8:INTEGER:ASCENDING)
1 ,RECORDTYPE='FIXED'
1 ,FORM='UNFORMATTED')
:
:
READ (KEYEQ=4,UNIT=INDXUFLUN)J,K
FPT writes:
C FPT OPEN (UNIT=indxuflun,ACCESS='SEQUENTIAL'
C 1 ,FILE='INDXUF.DAT',RECL=10,STATUS='NEW'
C 1 ,ORGANIZATION='INDEXED'
C 1 ,KEY=(1:4:INTEGER,5:8:INTEGER:ASCENDING)
C 1 ,RECORDTYPE='FIXED'
C 1 ,FORM='UNFORMATTED')
CALL vxrms_open('UNIT=',indxuflun,'ACCESS=','SEQUENTIAL','FILE=',
1 'INDXUF.DAT','RECL=',10,'STATUS=','NEW','ORGANIZATION=','INDEXED'
1 ,'KEY=',1,4,'INTEGER','ASCENDING','KEY=',5,8,'INTEGER',
1 'ASCENDING','RECORDTYPE=','FIXED','FORM=','UNFORMATTED',%VAL(0))
:
:
C FPT - Statement modified for VXRMS
C FPT READ (KEYEQ=4,UNIT=indxuflun)j,k
CALL vxrms_read('I4KEYEQ=',4,'UNIT=',indxuflun,%VAL(0))
CALL vxrms_unpack_buffer(%REF(j),4,%REF(k),4,%VAL(0))
The code remains reasonably readable, and close enough to the Fortran
standard to compile on nearly all systems.
|
|
Under VMS you can read a REAL*4 as a REAL*8 or vice versa with no greater
penalty than a loss in precision. This will not work with IEEE numbers.
Also, on a small-ended machine you can read an INTEGER*2 from an INTEGER*4
location with reasonable safety. You get the wrong end of the word with
a big-ended machine.
If you start, for example, with:
REAL*8 RUDDER_CMD,RUDDER_ACT
:
:
CALL BOUND(RUDDER_ACT,-27.0,RUDDER_CMD,27.0)
Where BOUND is defined as
SUBROUTINE BOUND(BOUNDED,LOW,INPUT_VALUE,HIGH)
REAL*8 BOUNDED,LOW,INPUT_VALUE,HIGH
BOUNDED=MIN(HIGH,MAX(LOW,INPUT_VALUE))
RETURN
END
WinFPT or FPT generates the output:
REAL*8 rudder_cmd,rudder_act
:
:
CALL bound(rudder_act,-27.0D0,rudder_cmd,27.0D0)
!-------------------------------^-----------------^----------------------------
!!! FPT - 1873 Actual argument has been changed to match formal argument.
!!! FPT - 1873 Actual argument has been changed to match formal argument.
!------------------------------------------------------------------------------
In one VMS to Unix migration we fixed about 6000 of these in a single pass.
FPT will also supply missing arguments, which is a common issue in VMS systems calls.
|
|
Under VMS, Fortran PARAMETER statements may be written without parentheses. The
data type of the parameter is then determined by the data type of the parameter value,
not by the current IMPLICIT rules or by prior data type declarations.
These parameter statements are not usually supported by Linux, Unix or Windows compilers.
WinFPT and FPT convert them to standard declarations.
For example, the code:
PARAMETER PBIT0=1,PBIT1=2,PBIT3=4,PBIT4=8
PARAMETER COEFF_SOURCE='AEROCOEFF.DAT'
PARAMETER PI=4.0D0*ATAN(1.0D0)
becomes:
INTEGER*4 pbit0
INTEGER*4 pbit1
INTEGER*4 pbit3
INTEGER*4 pbit4
PARAMETER (pbit0=1,pbit1=2,pbit3=4,pbit4=8)
CHARACTER*13 coeff_source
PARAMETER (coeff_source='AEROCOEFF.DAT')
REAL*8 pi
PARAMETER (pi=4.0D0*ATAN(1.0D0))
|
|
A common VMS trick is to bury variables inside format statements or format
expressions, e.g.
WRITE(6,'(''Value of X: '',1F<IW>.<IW-INT(LOG10(X))-3>)')X
This doesn't work with most Unix and Windows compilers. Converted by FPT it becomes:
INCLUDE 'embedded_expression_cmn.fpi'
:
:
! FPT WRITE (6,'(''Value of X: '',1F<iw>.<iw-INT(LOG10(x))-3>)')x
WRITE (embedded_expressions(1),'(1I10)')iw
WRITE (embedded_expressions(2),'(1I10)')iw-INT(LOG10(x))-3
WRITE (6,'(''Value of X: '',1F'//embedded_expressions(1)//'.'//
!----------------------------------------------------------^-------------------
!!! FPT - 1819 Embedded expression of the form <...> has been replaced
!------------------------------------------------------------------------------
1 embedded_expressions(2)//')')x
!--------------------------^---------------------------------------------------
!!! FPT - 1819 Embedded expression of the form <...> has been replaced
!------------------------------------------------------------------------------
The conversion works on formats written within the I/O statements and on
separate FORMAT statements.
|
|
These are issues in the way in which the names, numbers, keywords and other
tokens are written, and the way in which they are combined to make statements.
Many of the changes required take only a few hours with a text editor. The
danger of this approach is that the modified code no longer runs under VMS, so
the codes for the two hosts immediately start to diverge. Also, the code passes
through an intermediate stage during which it will not compile and run on either
platform.
WinFPT and FPT automate the changes, which may be made in a few seconds.
|
|
These are issues where the meanings of the tokens affect the changes which
must be made. Often, the changes required are structural and affect more than
one statement.
WinFPT and FPT will handle all of these issues, usually with a one line command, or in WinFPT, a couple
of mouse clicks.
|
 |
|
|
|