fpt and WinFPT Reference Manual - Command-line Commands
| SimCon Home | Ref Manual Home |
Commands for Migration
Note: For an introduction to Fortran migration please see the Migration page. Some of the changes described under Software Engineering may also be of value for migration.
Source File Handling - File Names in INCLUDE Statements
Please see the description of Running fpt and Output File handling for further descriptions of the commands to handle file names.
Source Code Layout
INPUT CODE LAYOUT: The available layouts are free format, fixed format and fixed format with 132 character lines. Commands are available to truncate code at column 72 or column 132, or to accept very long lines. Code from VMS, from DEC/Compaq Visual Fortran and some other systems may be written in tab format. The leading tab characters may cause problems, particularly on contuation lines, with some compilers. fpt accepts (and can also write) tab format. Different layouts may be specified for different files within the same project, and the layout may be inferred from the file name extension.
Note that it is important to be able to move code back from free format to fixed format when the original host cannot compile free format code. Modifications may then be tested in the original environment.
FIXED FORMAT OUTPUT, FREE FORMAT OUTPUT: Free format is preferred, but fixed format may be required to compile the code on the original host.
Please see formatting Fortran Code for a further description.
The microsyntax describes the way in which code lines, keywords, operators and user-defined symbols are written. Legacy systems contain a number of extensions which may have to be translated.
CHANGE COMMENT DELIMITER: Changes the line comment delimiter in column 1. Some legacy systems use the characters D (e.g. VMS) or X and Y (MPX) as optional comment delimiters.
CHANGE TRAILING COMMENT DELIMITER: Changes the trailing comment delimiter to ! . Some systems, e.g. Salford FTN77, allow /*.
NO TRAILING COMMENTS: Trailing comments are converted to line comments. This is required by some old Unix systems.
CHANGE EMBEDDED TABS TO SPACES, REMOVE EMBEDDED TABS: Tab characters within the code line are not accepted by some compilers. The position of the end of the code line is preserved in fixed format to protect undelimited trailing comments.
TRUNCATE INPUT LINES: Fixed format lines are truncated at column 72 to remove the line number written in columns 73-80 by some legacy systems (e.g. MPX).
CHANGE STRING DELIMITER: Some legacy systems use up arrow as a string delimiter. Others do not allow the use of double quotes.
ACCEPT CHARACTER: Accepts the characters :, $, %, @ and # as alphabetic characters in symbol names and/or keywords. Each of these (even :) is accepted by at least one legacy system. The ACCEPT CHARACTER command is used to instruct fpt to accept them, and the EDIT SYMBOL NAMES command may be used to change them.
EDIT SYMBOL NAMES systematically edits all of the symbol names in the code. Comments, keywords, operators, delimited strings and Hollerith constants are not changed.
TRUNCATE NAMES AFTER ...: Only the specified number of characters is used to identify the symbol name. All of the names which match up to this number of characters are changed systematically to match the first occurrence of the name. Names in Gould-SEL (Encore) Fortran must be handled in this way because only the first 8 charactrs are significant.
CHANGE OCTAL NUMBERS, CHANGE HEX NUMBERS: Reformat the numbers to the requested format.
CHANGE RECORD SPECIFICATIONS: Replaces the legacy direct access unit and record syntax, e.g. WRITE(3'RECNO), with standard Fortran format, e.g. WRITE(3,REC=RECNO).
COUNT TRAILING WHITE SPACE IN STRINGS: This command controls handling of strings which extend across one or more continuation lines in fixed format. The alternatives are to pad the string with spaces up to column 72, or to count the number of white space characters actually written on the line. Compilers vary in the way in which this is handled. fpt inserts string delimiters to remove the ambiguity.
MAXIMUM NUMBER OF CONTINUATION LINES: Specifies the maximum number. Statements which are too long are compressed by suspending the formatting rules, or, if possible, are split into separate statements.
Changes in Syntax
CHANGE DEFINE FILE TO OPEN: This command replaces the obsolete and non-standard DEFINE FILE commands by OPEN statements.
COMMENT OUT ...: This command removes non-standard and often non-essential features such as OPTION, OPTIONS, PAGE and UNLOCK statements. Embedded assembler code may be commented-out and is marked in the code so that users may re-program it. There is also provision to remove opening of the terminal, which causes problems on some systems.
REMOVE %DESCR: The argument passing protocol directive %DESCR is systematically removed from the code. This may be necessary when migrating from VMS. Under VMS, character arguments are normally passed by descriptor but the mechanism is not supported in other operating systems.
fpt may be used systematically to change between alternative forms of declaration statements, for example, between INTEGER(KIND=ki1), INTEGER*1 and BYTE. The commands are:
CHANGE PARAMETER STATEMENTS TO STANDARD FORM: This command changes the FORTRAN IV format PARAMETER statements without parentheses to standard Fortran 77 / 90 format.
ADD PARENTHESES TO FUNCTION DECLARATIONS: Some systems allow the declaration of functions without arguments to be written without empty open and close parentheses. This is non-standard. The parentheses are supplied.
CHANGE .EQ. FOR LOGICAL: The operators .EQ. and .NE. are replaced by .EQV. and .NEQV. in comparisons between logical objects. The .EQ. and .EQV. operators have different precedence and parentheses are added where appropriate to preserve the original behaviour.
CHANGE INTRINSICS TO GENERIC FORM: Some legacy systems, in particular VMS, support a number of non-standard intrinsic functions. This command replaces all intrinsic functions which are data type and kind specific by the generic equivalents.
CHANGE DECODE and CHANGE ENCODE: The non-standard DECODE and ENCODE statements are replaced by internal READ and WRITE statements.
CHANGE WHILE DO and CHANGE DO UNTIL TO DO WHILE: DO - UNTIL and WHILE - DO statements are non-standard variants of DO - WHILE constructs. The constructs are systematically converted to standard Fortran 90 syntax.
CHANGE SELECT CASE TO IF-THEN-ELSE: SELECT CASE is supported with non-standard syntax by some legacy systems (e.g. MPX) and is unsupported by some others. The statements, either in standard Fortran 90 syntax or in MPX syntax are converted to standard IF-THEN-ELSE constructs.
REMOVE EMBEDDED EXPRESSIONS FROM FORMATS: Some compilers, e.g. VMS, HP-UX and Compaq Visual Fortran, support variables and expressions embedded in FORMAT statements and in format specifications within I/O statements. The embedded expressions are enclosed in < > brackets. The code is translated to standard Fortran 77 / Fortran 90 syntax.
CHANGE MULTIPLE ASSIGNMENTS TO SEPARATE STATEMENTS: Multiple assignments are split into separate statements. They are unsupported on many legacy systems.
EXPAND INTERNAL SUB-PROGRAMS INLINE: Internal sub-programs are unsupported by most legacy systems, and supported with non-standard syntax under MPX. The sub-programs, either with standard or with MPX syntax, are expanded in-line.
CHANGE EXTENDED MEMORY STATEMENTS TO STANDARD FORM: The Gould-SEL (Encore) statements used to manage extended memory are commented-out, and where appropriate are translated to standard Fortran.
Issues in Passing Sub-program Arguments
Most of the issues described above cause compilation errors if the original system and the migration target are not compatible. If the code compiles on the new system the commands are probably unnecessary. The issues in mis-matched sub-program arguments usually cause problems at run-time and are usually harder to debug.
A common problem arises because of the different floating point number formats on modern and legacy machines. The 4-byte and 8-byte numbers on VAX/VMS and Gould-SEL MPX machines were designed so that a REAL*8 value can be passed as an actual argument to a routine where the formal argument is REAL*4, and the 4-byte value received is correct to within one least significant bit. Similarly, a REAL*4 can be passed to a routine where the formal argument is REAL*8, and the REAL*8 value is still accurate to REAL*4 precision. With the IEEE number formats used by PC based systems, the different real kinds are not compatible in this way. The mis-matched arguments cause serious numerical errors.
CHECK ARGUMENTS: The CHECK ARGUMENTS command may be used to indicate the extent of the potential problem. If a large number of mis-matched arguments are reported it may be possible to correct many of them systematically with the commands described below.
CORRECT INCONSISTENT ARGUMENTS: This command corrects inconsistent arguments where the inconsistency is in data type and data size, and in some cases, in data passing protocol. The corrections are marked by diagnostic messages in the code so they may easily be found and inspected.
CORRECT INCONSISTENT STRING ARGUMENTS TO ...: This command specifies the way in which inconsistent string arguments are to be corrected. Inconsistent string arguments usually occur where character strings are stored in numeric variables. The inconsistency is then in the argument passing protocol.
CORRECT MISSING ARGUMENTS: Placeholders are provided for missing arguments which are not declared to be optional.
MISSING ARGUMENTS TO BE REPLACED BY ..., DEFAULT LENGTH OF MISSING STRING ARGUMENTS: These commands specify the ways in which missing arguments are to be replaced. Missing character arguments may be of unspecified size if the formal argument is declared CHARACTER*(*) and a default must then be used.
PASS STRING ARGUMENTS BY ...: This command specifies the default argument passing mechanism for character variables. The alternatives are REFERENCE, VALUE DESCRIPTOR and ADDRESS AND LENGTH Optionally, these commands are written in comments in the Fortran code to specify the argument passing protocols of specific arguments. By default, it is assumed that numeric arguments are passed by reference, and that character arguments will be passed by address and length. The default for character arguments may be changed by the command PASS STRING ARGUMENTS BY .... This information is used to check that the arguments are passed correctly, and optionally to attempt correction if they are not.
VARIANT, OPTIONAL and REPEATED: These commands are optionally written in comments in the code to specify attributes of arguments. The VARIANT attribute specifies that the data type and kind of the argument is not to be checked by fpt.
Non-standard and Misleading Usages - When Things Are Not What They Seem
The commands described in this section handle some of the traps in Fortran migration. The constructs they deal with usually look like standard Fortran, and the un-modified code will often compile and link. It will then run incorrectly.
DATAPOOL declarations are introduced by the keyword COMMON and look like conventional COMMON block declarations. However, the Gould-SEL DATAPOOL is quite unlike a normal COMMON block. Please see the command set for this construct in the DATAPOOL section below.
SPECIFY GLOBAL SAVE: Some legacy systems (in particular VMS) reserve static memory for all local variables by default. The behaviour is as if a global SAVE statement were written at the start of every sub-program, and many legacy codes rely on this feature to function correctly. This comand inserts SAVE statements to emulate the behaviour.
PAD COMMON BLOCKS and PAD STRUCTURES: Some systems automatically, and silently, insert padding into COMMON blocks and structures in order to align variables. This has been observed, for example, on Gould-SEL systems. Legacy codes may rely on this padding to maintain the integrity of EQUIVALENCE relationships, and it must be emulated if the Database for Interactive Control mechanism is used. These commands insert padding variables and %FILL statements explicitly to emulate the behaviour.
SEARCH FOR EXTERNAL PARAMETERS: External parameters are pre-defined Fortran parameters which are available in VMS Fortran. The value of the parameter is obtained as %LOC( PARAMETER_NAME ). The parameters are also defined in INCLUDE files available on the VMS system. The construct is recognised by fpt, and this command specifies the INCLUDE files which contain the parameter declarations. The construct is re-programmed as standard Fortran 77, inserting the appropriate declarations and removing the %LOC intrinsic function invocation.
CHANGE INTRINSIC: This command substitutes the name of one intrinsic function for another. In some (not all) Gould-SEl systems, the trigonometric intrinsics accept arguments in degrees, not in radians. The code may be corrected by specifying, for example, CHANGE INTRINSIC SIN TO SIND.
CHANGE CALL FUNCTION TO FUNCTION INVOCATION: Some compilers, e.g. VMS, allow functions to be called as if they were subroutines. On other systems this will fail, either at link time or at run-time. The code is automatically corrected and the function return is written to a new variable which is declared but otherwise unused.
CORRECT USE OF INTEGER FOR LOGICAL: Some systems, in particular VMS, allowed integer variables to be used in logical IF statements as if they were logical variables. When code is migrated this may lead to compilation errors, but more often, the code compiles but does not run correctly. This command encloses the integer variable in an expression which returns a logical value.
REPRESENT TRUE BY ...: This command specifies the way in which a logical value is to be generated from an integer. The alternatives are to use the zero or non-zero status (Most Linux systems), the least significant bit (VMS) or the sign bit.
SEPARATE DO AND GOTO LABELS: Most Fortran systems allow a GOTO or alternate return to transfer control to the label of the statement which ends a DO loop from inside the loop. At least one (Gould-SEL) allows transfer of control from outside the loop. This command generates a new label and separates the two constructs to make program flow unambiguous.
ENCAPSULATE READ ACCESS TO INTEGER*1 OBJECTS: On at least one legacy system (Gould-SEL) the INTEGER*1 data type is unsigned. In consequence an INTEGER*1 variable can hold values in the range 128-255, and these values may even index arrays. It also appears to be legal to assign a negative values to an INTEGER*1 variable but the value is unsigned when it is used. This routine encapsulates all read accesses to INTEGER*1 variables and returns an INTEGER*4 value which corresponds to the unsigned INTEGER*1 value. This command must be used in migrating from Gould-SEL systems.
PROTECT AGAINST DIVISION BY ZERO This command replaces all integer, real amd complex division operators where the denominator is a variable with function invocations. The functions check for a denominator close to zero, return a user-defined value and the program continues execution. This command is important in migrating real-time control codes, such as those of flight simulators, where a program exception could result in an unsafe situation. It emulates the behaviour of Gould-SEL (Encore) MPX Fortran.
REDIRECT LOGICAL UNIT TO TERMINAL: This command systematically changes the specified I/O logical unit to the current terminal input or output unit. By default, the terminal input and output units are 5 and 6 respectively, but they may be changed by the commands TERMINAL INPUT UNIT and TERMINAL OUTPUT UNIT.
VOLATILE: This command is written in the code to declare that a variable or COMMON block may be changed from outside the flow of the program. This information is used in data flow analysis.
The original system may support intrinsic functions which are unsupported on the migration target (or vice-versa). These commands provide facilities to handle this situation.
CHANGE INTRINSICS TO GENERIC FORM: All INTRINSIC functions are replaced by their generic equivalents. The compiler should then infer the data types, kinds and data sizes from those of the arguments. This command is particularly useful in migration from systems such as VMS where there are large numbers of different intrinsic functions specific to different integer data sizes.
NON-INTRINSIC: Specifies that a function is not intrinsic on the migration target. Note that fpt handles intrinsic functions and user-defined functions differently in processing the code.
EVALUATE INTRINSICS IN PARAMETER STATEMENTS: Fortran parameter definitions which contain intrinsic function invocations are replaced by the literal values of the parameters. Not all compilers will accept all intrinsic functions in PARAMETER statements. The Fortran Standard specifies which are to be accepted, but compilers vary in the way in which this is handled.
Interfaces to C and Other Languages
INSERT HEADER FILE: An INCLUDE statement for the specified file is inserted after the last USE or IMPLICIT statement in every sub-program. This allows the declaration, for example, of functions used to translate assembler code or non-standard intrinsic functions.
INSERT ARGUMENT COUNT: This command inserts the argument count as a leading argument in the specified routine. This may be important where system library routines are replaced by user-written code, or by routines from the Sector7 VMS emulation libraries.
ARGUMENT COUNT INSERTED: This command is inserted in the program code by fpt to indicate that an argument count has already been inserted in a sub-program call, and prevents the insertion of a second argument count if fpt is re-run.
Foreign Data Types
BIT PATTERN: This command is written in the code to specify that a variable is a foreign data type. This information is used in the INSERT RECORD REPLAY mechanism.
INSERT TRANSLATIONS OF FOREIGN OBJECTS: Specifies whether or not fpt is to insert translation functions for read and write access to objects of foreign data types.
FILE NAME: This is written in the code to specify that the named variable holds file names. A translation function may then be inserted where the name is used to translate between the different file name formats used by different operating systems.
INSERT FUNCTION TO TRANSLATE FILE NAMES or INSERT SUBROUTINE TO TRANSLATE FILE NAMES: These commands instruct fpt to insert translation functions or translation subroutines for file names.
TRANSLATION FUNCTION FOR FILENAMES and TRANSLATION SUBROUTINE FOR FILENAMES: These commands specify the translation function or subroutine for file names.
TRANSLATION FUNCTION INSERTED: This is written in the code output by fpt to indicate that a translation function has been inserted. It prevents the insertion of a second translation if fpt is re-run.
The Gould-SEL (Encore) DATAPOOL is a COMMON block which may be shared by multiple programs. The addresses of the variables in the DATAPOOL are held in a database by the MPX operating system. They are not, therefore, necessarily in the positions or order specified in the DATAPOOL statements written in the sub-program code (even though these look like conventional COMMON block statements). An extensive tool-set is provided to migrate and to support the DATAPOOL on standard Linux, Unix, OSX and Windows systems.
CHANGE DATAPOOL TO A STANDARD COMMON: The declarations of the DATAPOOL and of the objects in it are removed from the code. An INCLUDE file is created which contains the type declarations of the variables, including any associated comments, and COMMON statements which set out the DATAPOOL address structure in a conventional Fortran COMMON block. INCLUDE statements for the INCLUDE file are inserted wherever they are needed.
DATAPOOL LISTING FILE: This command specifies the name of the file which describes the address allocation in the DATAPOOL. The file may be in either of two formats. A Gould-SEL (Encore) MPX system can generate a listing which shows the addresses of the variables in the DATAPOOL, and the file may be in the format of this listing. Alternatively, fpt can generate a listing file derived from the MPX listing. The file generated by fpt contains more information about the variables, and is in a more readable format.
WRITE DATAPOOL TEXT FILE: This command instructs fpt to write the text file which describes the DATAPOOL.
BUILD ACCESS DATABASE: Tools are available under MPX to inspect and change DATAPOOL variables at run-time. These tools are emulated by the BUILD ACCESS DATABASE mechanism.
ISAM, Indexed Sequential Access Mechanism, files were widely used under the VMS operating system to produce efficient databases. The search mechanism is highly efficient for search paths which are known at the time when the ISAM file is created. However, the creation of new search paths requires re-writing of the file. Sector7 Inc. provides a library which supports ISAM files on non-VMS hosts, and the commands described here map onto that library.
CHANGE ALL / FILE IO TO SUB-PROGRAM CALLS, CHANGE FILE I/O TO SUB-PROGRAM CALLS or CHANGE ISAM FILE ACCESSES TO SUB-PROGRAM CALLS: These commands specify that all I/O statements, all file I/O statements or all known ISAM file I/O statements are to be replaced by calls to the ISAM library routines. Each ISAM file access is enclosed in a test to find whether or not the target file is an ISAM file. If it is not, the original I/O statement is executed. ISAM logical units are identified from context or from user-written specifications as described below.
INDEXED UNIT: Specifies whether or not the specified logical unit number is used for ISAM files.
INFER INDEXED UNITS FROM USAGE: Specifies that ISAM units are to be recognised from the way in which they are used in the code.
VXRMS LIBRARY ID: Specifies the version of the Sector7 VXRMS library in use.
VXRMS TEMPORARY LOGICAL UNIT: Specifies a Fortran logical unit on which a temporary file used by the VXRMS library is to be opened.
VXRMS TO USE PACK BUFFER: Specifies the mechanism for data transfer to be used by the VXRMS library.
Copyright ©1995 to 2023 Software Validation Ltd. All rights reserved.