fpt and WinFPT Reference Manual - Command-line Commands

| SimCon Home | Ref Manual Home |

CPP Directive and Macro Handling

CPP Directives

fpt recognises the following cpp directives written in the Fortran code:

#define #undef #if #ifdef #ifndef #elif #else #endif #include

The commands #define and #undef may also be written in specification (fsp) files. When they are written in fsp files these commands are position sensitive and the macro definitions are applied to all files which follow the directives. The macros are also applied to all include files referenced by #include directives, but not to include files referenced by Fortran INCLUDE statements.

The directives are written in the style which conforms to gnu cpp with the -traditional -C -P switches. The # character must be written in column 1. White space may, but is not required to separate the # character from the keyword. The keywords must be written in lower case (Note that all other fpt commands are case insensitive).

Macros defined by the #define command are case sensitive and are position sensitive in the Fortran files in which the #define and #undef commands are written. The macros are defined in the same way as in cpp. The opening parenthesis which introduces the arguments must be written after the macro name with no intervening white space characters. The macro definition is separated from the macro name and the arguments (if any) by one or more white space characters. The macros are expanded in the Fortran code and fpt always analyses the code after macro expansion. They ae interpreted wherever they occur, but the expansions need not be written in the Fortran output files generated by fpt. This behaviour is controlled by the commands:

Defaults

Two macros are pre-defined:

__FILE__ The current file name, without the directory name
__LINE__ The line number within the current file

The default setting for writing and displaying the Fortran code is %HIDE CPP. The output code may then be pre-processed and built in exactly the same way as the input code.

Example

The subroutine td_setup sets up a display of the range and doppler shift of an array of targets. The specification (fsp) file for the tracking radar project begins with the macro definition:

! tracker_4412.fsp 27-2-1010 John Christopherson ! ************************************************************************* #define REPORT_ERROR(STATUS) CALL report_error(__FILE__,__LINE__,STATUS)

Note that the macro REPORT_ERROR invokes the pre-defined macros __FILE__ and __LINE__.

The code of td_setup contains the fragment:

DO i=1,n_targets CALL get_tracking_display(i, td_range, td_doppler, targets, & #ifdef MULTIPATH horizon_1,horizon_2 & #endif istat) IF (istat /= 0) THEN REPORT_ERROR(istat) ENDIF ENDDO

There are two variants of this routine, a simple line-of-sight model and a version which models knife-edge refraction at two successive horizons. The horizons around the radar system are represented by two arrays, horizon_1 and horizon_2, which record the elevation and range of the horizons as a function of bearing. The version in use is selected by the CPP macro MULTIPATH. In this example MULTIPATH is not defined.

The code is processed by fpt and is examined interactively with the three settings for cpp macro display:

HIDE CPP is the default setting. The code is analysed by fpt but is reproduced with the cpp macros in the format in which they were originally written:

FPT> hide cpp FPT> type 111:122 111 ! 112 DO i=1,n_targets 113 CALL get_tracking_display(i,td_range,td_doppler,targets, & 114 #ifdef MULTIPATH 115 horizon_1,horizon_2 & 116 #endif 117 istat) 118 IF (istat/=0) THEN 119 REPORT_ERROR(istat) 120 ENDIF 121 ENDDO 122 !

SHOW CPP is used to display the macros and the interpretation of the macros in the same text. Note that this code will not compile. The display is used to inspect the macro expansions:

FPT> show cpp FPT> type 112:122 112 DO i=1,n_targets 113 CALL get_tracking_display(i,td_range,td_doppler,targets, & 114 !CPP! #ifdef MULTIPATH 115 !CPP! horizon_1,horizon_2 & 116 !CPP! #endif 117 istat) 118 IF (istat/=0) THEN 119 REPORT_ERROR(istat) << CALL report_error("td_setup.f90", & 119 119,istat) >> 120 ENDIF 121 ENDDO

Note that the unused code at line 115 is commented-out. This code is not analysed by fpt. It is handled internally as if it were a comment. In consequence, commands such as rename symbol will not change this code. Note that the macro expansion of REPORT_ERROR is shown within << >> delimiters.

EMULATE CPP is used to generate code which may be compiled without using cpp to pre-process it again. In most cases, the code generated matches that which would be generated if the code were to be processed first by cpp and then by fpt. There are exceptions in the handling of #include and ## constructs. Please see the description of EMULATE CPP for further information).

FPT> emulate cpp FPT> type 112:122 112 DO i=1,n_targets 113 CALL get_tracking_display(i,td_range,td_doppler,targets, & 114 115 116 117 istat) 118 IF (istat/=0) THEN 119 CALL report_error("td_setup.f90",119,istat) 120 ENDIF 121 ENDDO

Note that the cpp directives and the unused code at line 115 removed and replaced by blank lines. The macro expansion of REPORT_ERROR is complete. The original macro text is removed.

Copyright ©1995 to 2024 Software Validation Ltd. All rights reserved.